MCPcopy Create free account
hub / github.com/apache/singa / pow

Function pow

include/half.hpp:3402–3449  ·  view source on GitHub ↗

Power function. This function may be 1 ULP off the correctly rounded exact result for any rounding mode in ~0.00025% of inputs. See also:** Documentation for [std::pow](https://en.cppreference.com/w/cpp/numeric/math/pow). \param x base \param y exponent \return \a x raised to \a y \exception FE_INVALID if \a x or \a y is signaling NaN or if \a x is finite an negative and \a y is finite and not in

Source from the content-addressed store, hash-verified

3400 /// \exception FE_DIVBYZERO if \a x is 0 and \a y is negative
3401 /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding
3402 inline half pow(half x, half y)
3403 {
3404 #ifdef HALF_ARITHMETIC_TYPE
3405 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_))));
3406 #else
3407 int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -15;
3408 if(!absy || x.data_ == 0x3C00)
3409 return half(detail::binary, detail::select(0x3C00, (x.data_==0x3C00) ? y.data_ : x.data_));
3410 bool is_int = absy >= 0x6400 || (absy>=0x3C00 && !(absy&((1<<(25-(absy>>10)))-1)));
3411 unsigned int sign = x.data_ & (static_cast<unsigned>((absy<0x6800)&&is_int&&((absy>>(25-(absy>>10)))&1))<<15);
3412 if(absx >= 0x7C00 || absy >= 0x7C00)
3413 return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) :
3414 (absy==0x7C00) ? ((absx==0x3C00) ? 0x3C00 : (!absx && y.data_==0xFC00) ? detail::pole() :
3415 (0x7C00&-((y.data_>>15)^(absx>0x3C00)))) : (sign|(0x7C00&((y.data_>>15)-1U))));
3416 if(!absx)
3417 return half(detail::binary, (y.data_&0x8000) ? detail::pole(sign) : sign);
3418 if((x.data_&0x8000) && !is_int)
3419 return half(detail::binary, detail::invalid());
3420 if(x.data_ == 0xBC00)
3421 return half(detail::binary, sign|0x3C00);
3422 if(y.data_ == 0x3800)
3423 return sqrt(x);
3424 if(y.data_ == 0x3C00)
3425 return half(detail::binary, detail::check_underflow(x.data_));
3426 if(y.data_ == 0x4000)
3427 return x * x;
3428 for(; absx<0x400; absx<<=1,--exp) ;
3429 detail::uint32 ilog = exp + (absx>>10), msign = detail::sign_mask(ilog), f, m =
3430 (((ilog<<27)+((detail::log2(static_cast<detail::uint32>((absx&0x3FF)|0x400)<<20)+8)>>4))^msign) - msign;
3431 for(exp=-11; m<0x80000000; m<<=1,--exp) ;
3432 for(; absy<0x400; absy<<=1,--exp) ;
3433 m = detail::multiply64(m, static_cast<detail::uint32>((absy&0x3FF)|0x400)<<21);
3434 int i = m >> 31;
3435 exp += (absy>>10) + i;
3436 m <<= 1 - i;
3437 if(exp < 0)
3438 {
3439 f = m >> -exp;
3440 exp = 0;
3441 }
3442 else
3443 {
3444 f = (m<<exp) & 0x7FFFFFFF;
3445 exp = m >> (31-exp);
3446 }
3447 return half(detail::binary, detail::exp2_post<half::round_style,false>(detail::exp2(f), exp, ((msign&1)^(y.data_>>15))!=0, sign));
3448 #endif
3449 }
3450
3451 /// \}
3452 /// \anchor trigonometric

Callers 4

TEST_FFunction · 0.50
TEST_FFunction · 0.50
Cpp>Method · 0.50
Cuda>Method · 0.50

Calls 11

halfClass · 0.85
selectFunction · 0.85
signalFunction · 0.85
poleFunction · 0.85
invalidFunction · 0.85
check_underflowFunction · 0.85
sign_maskFunction · 0.85
log2Function · 0.85
multiply64Function · 0.85
exp2Function · 0.85
sqrtFunction · 0.70

Tested by 2

TEST_FFunction · 0.40
TEST_FFunction · 0.40