Hyperbolic area tangent. This function is exact to rounding for all rounding modes. See also:** Documentation for [std::atanh](https://en.cppreference.com/w/cpp/numeric/math/atanh). \param arg function argument \return area tangent value of \a arg \exception FE_INVALID for signaling NaN or if abs(\a arg) > 1 \exception FE_DIVBYZERO for +/-1 \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT accordi
| 3905 | /// \exception FE_DIVBYZERO for +/-1 |
| 3906 | /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding |
| 3907 | inline half atanh(half arg) |
| 3908 | { |
| 3909 | #if defined(HALF_ARITHMETIC_TYPE) && HALF_ENABLE_CPP11_CMATH |
| 3910 | return half(detail::binary, detail::float2half<half::round_style>(std::atanh(detail::half2float<detail::internal_t>(arg.data_)))); |
| 3911 | #else |
| 3912 | int abs = arg.data_ & 0x7FFF, exp = 0; |
| 3913 | if(!abs) |
| 3914 | return arg; |
| 3915 | if(abs >= 0x3C00) |
| 3916 | return half(detail::binary, (abs==0x3C00) ? detail::pole(arg.data_&0x8000) : (abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_)); |
| 3917 | if(abs < 0x2700) |
| 3918 | return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1)); |
| 3919 | detail::uint32 m = static_cast<detail::uint32>((abs&0x3FF)|((abs>0x3FF)<<10)) << ((abs>>10)+(abs<=0x3FF)+6), my = 0x80000000 + m, mx = 0x80000000 - m; |
| 3920 | for(; mx<0x80000000; mx<<=1,++exp) ; |
| 3921 | int i = my >= mx, s; |
| 3922 | return half(detail::binary, detail::log2_post<half::round_style,0xB8AA3B2A>(detail::log2( |
| 3923 | (detail::divide64(my>>i, mx, s)+1)>>1, 27)+0x10, exp+i-1, 16, arg.data_&0x8000)); |
| 3924 | #endif |
| 3925 | } |
| 3926 | |
| 3927 | /// \} |
| 3928 | /// \anchor special |