Get exponentials for hyperbolic computation \param abs half-precision floating-point value \param exp variable to take unbiased exponent of larger result \param n number of BKM iterations (at most 32) \return exp(abs) and exp(-\a abs) as Q1.31 with same exponent
| 1648 | /// \param n number of BKM iterations (at most 32) |
| 1649 | /// \return exp(abs) and exp(-\a abs) as Q1.31 with same exponent |
| 1650 | inline std::pair<uint32,uint32> hyperbolic_args(unsigned int abs, int &exp, unsigned int n = 32) |
| 1651 | { |
| 1652 | uint32 mx = detail::multiply64(static_cast<uint32>((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29), my; |
| 1653 | int e = (abs>>10) + (abs<=0x3FF); |
| 1654 | if(e < 14) |
| 1655 | { |
| 1656 | exp = 0; |
| 1657 | mx >>= 14 - e; |
| 1658 | } |
| 1659 | else |
| 1660 | { |
| 1661 | exp = mx >> (45-e); |
| 1662 | mx = (mx<<(e-14)) & 0x7FFFFFFF; |
| 1663 | } |
| 1664 | mx = exp2(mx, n); |
| 1665 | int d = exp << 1, s; |
| 1666 | if(mx > 0x80000000) |
| 1667 | { |
| 1668 | my = divide64(0x80000000, mx, s); |
| 1669 | my |= s; |
| 1670 | ++d; |
| 1671 | } |
| 1672 | else |
| 1673 | my = mx; |
| 1674 | return std::make_pair(mx, (d<31) ? ((my>>d)|((my&((static_cast<uint32>(1)<<d)-1))!=0)) : 1); |
| 1675 | } |
| 1676 | |
| 1677 | /// Postprocessing for binary exponential. |
| 1678 | /// \tparam R rounding mode to use |