| 1315 | /// \exception FE_INVALID if value is not representable in type \a T |
| 1316 | /// \exception FE_INEXACT if value had to be rounded and \a I is `true` |
| 1317 | template<std::float_round_style R,bool E,bool I,typename T> T half2int(unsigned int value) |
| 1318 | { |
| 1319 | unsigned int abs = value & 0x7FFF; |
| 1320 | if(abs >= 0x7C00) |
| 1321 | { |
| 1322 | raise(FE_INVALID); |
| 1323 | return (value&0x8000) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max(); |
| 1324 | } |
| 1325 | if(abs < 0x3800) |
| 1326 | { |
| 1327 | raise(FE_INEXACT, I); |
| 1328 | return (R==std::round_toward_infinity) ? T(~(value>>15)&(abs!=0)) : |
| 1329 | (R==std::round_toward_neg_infinity) ? -T(value>0x8000) : |
| 1330 | T(); |
| 1331 | } |
| 1332 | int exp = 25 - (abs>>10); |
| 1333 | unsigned int m = (value&0x3FF) | 0x400; |
| 1334 | int32 i = static_cast<int32>((exp<=0) ? (m<<-exp) : ((m+( |
| 1335 | (R==std::round_to_nearest) ? ((1<<(exp-1))-(~(m>>exp)&E)) : |
| 1336 | (R==std::round_toward_infinity) ? (((1<<exp)-1)&((value>>15)-1)) : |
| 1337 | (R==std::round_toward_neg_infinity) ? (((1<<exp)-1)&-(value>>15)) : 0))>>exp)); |
| 1338 | if((!std::numeric_limits<T>::is_signed && (value&0x8000)) || (std::numeric_limits<T>::digits<16 && |
| 1339 | ((value&0x8000) ? (-i<std::numeric_limits<T>::min()) : (i>std::numeric_limits<T>::max())))) |
| 1340 | raise(FE_INVALID); |
| 1341 | else if(I && exp > 0 && (m&((1<<exp)-1))) |
| 1342 | raise(FE_INEXACT); |
| 1343 | return static_cast<T>((value&0x8000) ? -i : i); |
| 1344 | } |
| 1345 | |
| 1346 | /// \} |
| 1347 | /// \name Mathematics |