Scaling implementation. \param arg number to scale \param exp power of two to scale by \return scaled number
| 1719 | /// \param exp power of two to scale by |
| 1720 | /// \return scaled number |
| 1721 | static half scalbln(half arg, long exp) |
| 1722 | { |
| 1723 | unsigned int m = arg.data_ & 0x7FFF; |
| 1724 | if(m >= 0x7C00 || !m) |
| 1725 | return arg; |
| 1726 | for(; m<0x400; m<<=1,--exp) ; |
| 1727 | exp += m >> 10; |
| 1728 | uint16 value = arg.data_ & 0x8000; |
| 1729 | if(exp > 30) |
| 1730 | { |
| 1731 | if(half::round_style == std::round_toward_zero) |
| 1732 | value |= 0x7BFF; |
| 1733 | else if(half::round_style == std::round_toward_infinity) |
| 1734 | value |= 0x7C00 - (value>>15); |
| 1735 | else if(half::round_style == std::round_toward_neg_infinity) |
| 1736 | value |= 0x7BFF + (value>>15); |
| 1737 | else |
| 1738 | value |= 0x7C00; |
| 1739 | } |
| 1740 | else if(exp > 0) |
| 1741 | value |= (exp<<10) | (m&0x3FF); |
| 1742 | else if(exp > -11) |
| 1743 | { |
| 1744 | m = (m&0x3FF) | 0x400; |
| 1745 | if(half::round_style == std::round_to_nearest) |
| 1746 | { |
| 1747 | m += 1 << -exp; |
| 1748 | #if HALF_ROUND_TIES_TO_EVEN |
| 1749 | m -= (m>>(1-exp)) & 1; |
| 1750 | #endif |
| 1751 | } |
| 1752 | else if(half::round_style == std::round_toward_infinity) |
| 1753 | m += ((value>>15)-1) & ((1<<(1-exp))-1U); |
| 1754 | else if(half::round_style == std::round_toward_neg_infinity) |
| 1755 | m += -(value>>15) & ((1<<(1-exp))-1U); |
| 1756 | value |= m >> (1-exp); |
| 1757 | } |
| 1758 | else if(half::round_style == std::round_toward_infinity) |
| 1759 | value -= (value>>15) - 1; |
| 1760 | else if(half::round_style == std::round_toward_neg_infinity) |
| 1761 | value += value >> 15; |
| 1762 | return half(binary, value); |
| 1763 | } |
| 1764 | |
| 1765 | /// Exponent implementation. |
| 1766 | /// \param arg number to query |