Tangent function. This function is exact to rounding for all rounding modes. See also:** Documentation for [std::tan](https://en.cppreference.com/w/cpp/numeric/math/tan). \param arg function argument \return tangent value of \a arg \exception FE_INVALID for signaling NaN or infinity \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding
| 3589 | /// \exception FE_INVALID for signaling NaN or infinity |
| 3590 | /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding |
| 3591 | inline half tan(half arg) |
| 3592 | { |
| 3593 | #ifdef HALF_ARITHMETIC_TYPE |
| 3594 | return half(detail::binary, detail::float2half<half::round_style>(std::tan(detail::half2float<detail::internal_t>(arg.data_)))); |
| 3595 | #else |
| 3596 | int abs = arg.data_ & 0x7FFF, exp = 13, k; |
| 3597 | if(!abs) |
| 3598 | return arg; |
| 3599 | if(abs >= 0x7C00) |
| 3600 | return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_)); |
| 3601 | if(abs < 0x2700) |
| 3602 | return half(detail::binary, detail::rounded<half::round_style,true>(arg.data_, 0, 1)); |
| 3603 | if(half::round_style != std::round_to_nearest) |
| 3604 | switch(abs) |
| 3605 | { |
| 3606 | case 0x658C: return half(detail::binary, detail::rounded<half::round_style,true>((arg.data_&0x8000)|0x07E6, 1, 1)); |
| 3607 | case 0x7330: return half(detail::binary, detail::rounded<half::round_style,true>((~arg.data_&0x8000)|0x4B62, 1, 1)); |
| 3608 | } |
| 3609 | std::pair<detail::uint32,detail::uint32> sc = detail::sincos(detail::angle_arg(abs, k), 30); |
| 3610 | if(k & 1) |
| 3611 | sc = std::make_pair(-sc.second, sc.first); |
| 3612 | detail::uint32 signy = detail::sign_mask(sc.first), signx = detail::sign_mask(sc.second); |
| 3613 | detail::uint32 my = (sc.first^signy) - signy, mx = (sc.second^signx) - signx; |
| 3614 | for(; my<0x80000000; my<<=1,--exp) ; |
| 3615 | for(; mx<0x80000000; mx<<=1,++exp) ; |
| 3616 | return half(detail::binary, detail::tangent_post<half::round_style>(my, mx, exp, (signy^signx^arg.data_)&0x8000)); |
| 3617 | #endif |
| 3618 | } |
| 3619 | |
| 3620 | /// Arc sine. |
| 3621 | /// This function is exact to rounding for all rounding modes. |