Hyperbolic tangent. This function is exact to rounding for all rounding modes. See also:** Documentation for [std::tanh](https://en.cppreference.com/w/cpp/numeric/math/tanh). \param arg function argument \return hyperbolic tangent value of \a arg \exception FE_INVALID for signaling NaN \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding
| 3820 | /// \exception FE_INVALID for signaling NaN |
| 3821 | /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding |
| 3822 | inline half tanh(half arg) |
| 3823 | { |
| 3824 | #ifdef HALF_ARITHMETIC_TYPE |
| 3825 | return half(detail::binary, detail::float2half<half::round_style>(std::tanh(detail::half2float<detail::internal_t>(arg.data_)))); |
| 3826 | #else |
| 3827 | int abs = arg.data_ & 0x7FFF, exp; |
| 3828 | if(!abs) |
| 3829 | return arg; |
| 3830 | if(abs >= 0x7C00) |
| 3831 | return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_-0x4000)); |
| 3832 | if(abs >= 0x4500) |
| 3833 | return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x3BFF, 1, 1)); |
| 3834 | if(abs < 0x2700) |
| 3835 | return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-1, 1, 1)); |
| 3836 | if(half::round_style != std::round_to_nearest && abs == 0x2D3F) |
| 3837 | return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_-3, 0, 1)); |
| 3838 | std::pair<detail::uint32,detail::uint32> mm = detail::hyperbolic_args(abs, exp, 27); |
| 3839 | detail::uint32 my = mm.first - mm.second - (half::round_style!=std::round_to_nearest), mx = mm.first + mm.second, i = (~mx&0xFFFFFFFF) >> 31; |
| 3840 | for(exp=13; my<0x80000000; my<<=1,--exp) ; |
| 3841 | mx = (mx>>i) | 0x80000000; |
| 3842 | return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp-i, arg.data_&0x8000)); |
| 3843 | #endif |
| 3844 | } |
| 3845 | |
| 3846 | /// Hyperbolic area sine. |
| 3847 | /// This function is exact to rounding for all rounding modes. |