in include/half.hpp [3402:3449]
inline half pow(half x, half y)
{
#ifdef HALF_ARITHMETIC_TYPE
return half(detail::binary, detail::float2half<half::round_style>(std::pow(detail::half2float<detail::internal_t>(x.data_), detail::half2float<detail::internal_t>(y.data_))));
#else
int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -15;
if(!absy || x.data_ == 0x3C00)
return half(detail::binary, detail::select(0x3C00, (x.data_==0x3C00) ? y.data_ : x.data_));
bool is_int = absy >= 0x6400 || (absy>=0x3C00 && !(absy&((1<<(25-(absy>>10)))-1)));
unsigned int sign = x.data_ & (static_cast<unsigned>((absy<0x6800)&&is_int&&((absy>>(25-(absy>>10)))&1))<<15);
if(absx >= 0x7C00 || absy >= 0x7C00)
return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
(absy==0x7C00) ? ((absx==0x3C00) ? 0x3C00 : (!absx && y.data_==0xFC00) ? detail::pole() :
(0x7C00&-((y.data_>>15)^(absx>0x3C00)))) : (sign|(0x7C00&((y.data_>>15)-1U))));
if(!absx)
return half(detail::binary, (y.data_&0x8000) ? detail::pole(sign) : sign);
if((x.data_&0x8000) && !is_int)
return half(detail::binary, detail::invalid());
if(x.data_ == 0xBC00)
return half(detail::binary, sign|0x3C00);
if(y.data_ == 0x3800)
return sqrt(x);
if(y.data_ == 0x3C00)
return half(detail::binary, detail::check_underflow(x.data_));
if(y.data_ == 0x4000)
return x * x;
for(; absx<0x400; absx<<=1,--exp) ;
detail::uint32 ilog = exp + (absx>>10), msign = detail::sign_mask(ilog), f, m =
(((ilog<<27)+((detail::log2(static_cast<detail::uint32>((absx&0x3FF)|0x400)<<20)+8)>>4))^msign) - msign;
for(exp=-11; m<0x80000000; m<<=1,--exp) ;
for(; absy<0x400; absy<<=1,--exp) ;
m = detail::multiply64(m, static_cast<detail::uint32>((absy&0x3FF)|0x400)<<21);
int i = m >> 31;
exp += (absy>>10) + i;
m <<= 1 - i;
if(exp < 0)
{
f = m >> -exp;
exp = 0;
}
else
{
f = (m<<exp) & 0x7FFFFFFF;
exp = m >> (31-exp);
}
return half(detail::binary, detail::exp2_post<half::round_style,false>(detail::exp2(f), exp, ((msign&1)^(y.data_>>15))!=0, sign));
#endif
}