| 847 | /// \exception FE_INVALID for signaling NaN |
| 848 | /// \exception FE_INEXACT if value had to be rounded and \a I is `true` |
| 849 | template<std::float_round_style R,bool E,bool I> unsigned int integral(unsigned int value) |
| 850 | { |
| 851 | unsigned int abs = value & 0x7FFF; |
| 852 | if(abs < 0x3C00) |
| 853 | { |
| 854 | raise(FE_INEXACT, I); |
| 855 | return ((R==std::round_to_nearest) ? (0x3C00&-static_cast<unsigned>(abs>=(0x3800+E))) : |
| 856 | (R==std::round_toward_infinity) ? (0x3C00&-(~(value>>15)&(abs!=0))) : |
| 857 | (R==std::round_toward_neg_infinity) ? (0x3C00&-static_cast<unsigned>(value>0x8000)) : |
| 858 | 0) | (value&0x8000); |
| 859 | } |
| 860 | if(abs >= 0x6400) |
| 861 | return (abs>0x7C00) ? signal(value) : value; |
| 862 | unsigned int exp = 25 - (abs>>10), mask = (1<<exp) - 1; |
| 863 | raise(FE_INEXACT, I && (value&mask)); |
| 864 | return (( (R==std::round_to_nearest) ? ((1<<(exp-1))-(~(value>>exp)&E)) : |
| 865 | (R==std::round_toward_infinity) ? (mask&((value>>15)-1)) : |
| 866 | (R==std::round_toward_neg_infinity) ? (mask&-(value>>15)) : |
| 867 | 0) + value) & ~mask; |
| 868 | } |
| 869 | |
| 870 | /// Convert fixed point to half-precision floating-point. |
| 871 | /// \tparam R rounding mode to use |