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
| 4042 | /// negative \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to |
| 4043 | /// rounding |
| 4044 | inline half pow(half x, half y) { |
| 4045 | #ifdef HALF_ARITHMETIC_TYPE |
| 4046 | return half(detail::binary, |
| 4047 | detail::float2half<half::round_style>( |
| 4048 | std::pow(detail::half2float<detail::internal_t>(x.data_), |
| 4049 | detail::half2float<detail::internal_t>(y.data_)))); |
| 4050 | #else |
| 4051 | int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -15; |
| 4052 | if (!absy || x.data_ == 0x3C00) |
| 4053 | return half( |
| 4054 | detail::binary, |
| 4055 | detail::select(0x3C00, (x.data_ == 0x3C00) ? y.data_ : x.data_)); |
| 4056 | bool is_int = absy >= 0x6400 || |
| 4057 | (absy >= 0x3C00 && !(absy & ((1 << (25 - (absy >> 10))) - 1))); |
| 4058 | unsigned int sign = |
| 4059 | x.data_ & (static_cast<unsigned>((absy < 0x6800) && is_int && |
| 4060 | ((absy >> (25 - (absy >> 10))) & 1)) |
| 4061 | << 15); |
| 4062 | if (absx >= 0x7C00 || absy >= 0x7C00) |
| 4063 | return half(detail::binary, |
| 4064 | (absx > 0x7C00 || absy > 0x7C00) |
| 4065 | ? detail::signal(x.data_, y.data_) |
| 4066 | : (absy == 0x7C00) |
| 4067 | ? ((absx == 0x3C00) ? 0x3C00 |
| 4068 | : (!absx && y.data_ == 0xFC00) |
| 4069 | ? detail::pole() |
| 4070 | : (0x7C00 & -((y.data_ >> 15) ^ (absx > 0x3C00)))) |
| 4071 | : (sign | (0x7C00 & ((y.data_ >> 15) - 1U)))); |
| 4072 | if (!absx) |
| 4073 | return half(detail::binary, (y.data_ & 0x8000) ? detail::pole(sign) : sign); |
| 4074 | if ((x.data_ & 0x8000) && !is_int) |
| 4075 | return half(detail::binary, detail::invalid()); |
| 4076 | if (x.data_ == 0xBC00) return half(detail::binary, sign | 0x3C00); |
| 4077 | switch (y.data_) { |
| 4078 | case 0x3800: |
| 4079 | return sqrt(x); |
| 4080 | case 0x3C00: |
| 4081 | return half(detail::binary, detail::check_underflow(x.data_)); |
| 4082 | case 0x4000: |
| 4083 | return x * x; |
| 4084 | case 0xBC00: |
| 4085 | return half(detail::binary, 0x3C00) / x; |
| 4086 | } |
| 4087 | for (; absx < 0x400; absx <<= 1, --exp) |
| 4088 | ; |
| 4089 | detail::uint32 ilog = exp + (absx >> 10), msign = detail::sign_mask(ilog), f, |
| 4090 | m = (((ilog << 27) + |
| 4091 | ((detail::log2( |
| 4092 | static_cast<detail::uint32>((absx & 0x3FF) | 0x400) |
| 4093 | << 20) + |
| 4094 | 8) >> |
| 4095 | 4)) ^ |
| 4096 | msign) - |
| 4097 | msign; |
| 4098 | for (exp = -11; m < 0x80000000; m <<= 1, --exp) |
| 4099 | ; |
| 4100 | for (; absy < 0x400; absy <<= 1, --exp) |
| 4101 | ; |
no test coverage detected