Natural logarithm plus one. This function may be 1 ULP off the correctly rounded exact result in <0.05% of inputs for `std::round_to_nearest` and in ~1% of inputs for any other rounding mode. See also:** Documentation for [std::log1p](https://en.cppreference.com/w/cpp/numeric/math/log1p). \param arg function argument \return logarithm of \a arg plus 1 to base e \exception FE_INVALID for signaling
| 3165 | /// \exception FE_DIVBYZERO for -1 |
| 3166 | /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding |
| 3167 | inline half log1p(half arg) |
| 3168 | { |
| 3169 | #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH |
| 3170 | return half(detail::binary, detail::float2half<half::round_style>(std::log1p(detail::half2float<detail::internal_t>(arg.data_)))); |
| 3171 | #else |
| 3172 | if(arg.data_ >= 0xBC00) |
| 3173 | return half(detail::binary, (arg.data_==0xBC00) ? detail::pole(0x8000) : (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_)); |
| 3174 | int abs = arg.data_ & 0x7FFF, exp = -15; |
| 3175 | if(!abs || abs >= 0x7C00) |
| 3176 | return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg; |
| 3177 | for(; abs<0x400; abs<<=1,--exp) ; |
| 3178 | exp += abs >> 10; |
| 3179 | detail::uint32 m = static_cast<detail::uint32>((abs&0x3FF)|0x400) << 20; |
| 3180 | if(arg.data_ & 0x8000) |
| 3181 | { |
| 3182 | m = 0x40000000 - (m>>-exp); |
| 3183 | for(exp=0; m<0x40000000; m<<=1,--exp) ; |
| 3184 | } |
| 3185 | else |
| 3186 | { |
| 3187 | if(exp < 0) |
| 3188 | { |
| 3189 | m = 0x40000000 + (m>>-exp); |
| 3190 | exp = 0; |
| 3191 | } |
| 3192 | else |
| 3193 | { |
| 3194 | m += 0x40000000 >> exp; |
| 3195 | int i = m >> 31; |
| 3196 | m >>= i; |
| 3197 | exp += i; |
| 3198 | } |
| 3199 | } |
| 3200 | return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(detail::log2(m), exp, 17)); |
| 3201 | #endif |
| 3202 | } |
| 3203 | |
| 3204 | /// \} |
| 3205 | /// \anchor power |