in include/half.hpp [3124:3155]
inline half log2(half arg)
{
#if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH
return half(detail::binary, detail::float2half<half::round_style>(std::log2(detail::half2float<detail::internal_t>(arg.data_))));
#else
int abs = arg.data_ & 0x7FFF, exp = -15, s = 0;
if(!abs)
return half(detail::binary, detail::pole(0x8000));
if(arg.data_ & 0x8000)
return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_));
if(abs >= 0x7C00)
return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_));
if(abs == 0x3C00)
return half(detail::binary, 0);
for(; abs<0x400; abs<<=1,--exp) ;
exp += (abs>>10);
if(!(abs&0x3FF))
{
unsigned int value = static_cast<unsigned>(exp<0) << 15, m = std::abs(exp) << 6;
for(exp=18; m<0x400; m<<=1,--exp) ;
return half(detail::binary, value+(exp<<10)+m);
}
detail::uint32 ilog = exp, sign = detail::sign_mask(ilog), m =
(((ilog<<27)+(detail::log2(static_cast<detail::uint32>((abs&0x3FF)|0x400)<<20, 28)>>4))^sign) - sign;
if(!m)
return half(detail::binary, 0);
for(exp=14; m<0x8000000 && exp; m<<=1,--exp) ;
for(; m>0xFFFFFFF; m>>=1,++exp)
s |= m & 1;
return half(detail::binary, detail::fixed2half<half::round_style,27,false,false,true>(m, exp, sign&0x8000, s));
#endif
}