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
| 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 |