inline half cbrt()

in include/half.hpp [3239:3279]


	inline half cbrt(half arg)
	{
	#if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
		return half(detail::binary, detail::float2half<half::round_style>(std::cbrt(detail::half2float<detail::internal_t>(arg.data_))));
	#else
		int abs = arg.data_ & 0x7FFF, exp = -15;
		if(!abs || abs == 0x3C00 || abs >= 0x7C00)
			return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg;
		for(; abs<0x400; abs<<=1, --exp);
		detail::uint32 ilog = exp + (abs>>10), sign = detail::sign_mask(ilog), f, m = 
			(((ilog<<27)+(detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 24)>>4))^sign) - sign;
		for(exp=2; m<0x80000000; m<<=1,--exp) ;
		m = detail::multiply64(m, 0xAAAAAAAB);
		int i = m >> 31, s;
		exp += i;
		m <<= 1 - i;
		if(exp < 0)
		{
			f = m >> -exp;
			exp = 0;
		}
		else
		{
			f = (m<<exp) & 0x7FFFFFFF;
			exp = m >> (31-exp);
		}
		m = detail::exp2(f, (half::round_style==std::round_to_nearest) ? 29 : 26);
		if(sign)
		{
			if(m > 0x80000000)
			{
				m = detail::divide64(0x80000000, m, s);
				++exp;
			}
			exp = -exp;
		}
		return half(detail::binary, (half::round_style==std::round_to_nearest) ?
			detail::fixed2half<half::round_style,31,false,false,false>(m, exp+14, arg.data_&0x8000) :
			detail::fixed2half<half::round_style,23,false,false,false>((m+0x80)>>8, exp+14, arg.data_&0x8000));
	#endif
	}