Joseph Myers | 7537c2b | 2020-05-04 23:37:54 +0000 | [diff] [blame] | 1 | /* Test conversions of signaling NaNs to and from long double. */ |
| 2 | |
| 3 | #include <stdint.h> |
| 4 | #include <stdio.h> |
| 5 | |
| 6 | volatile float f_res; |
| 7 | volatile double d_res; |
| 8 | volatile long double ld_res; |
| 9 | |
| 10 | volatile float f_snan = __builtin_nansf(""); |
| 11 | volatile double d_snan = __builtin_nans(""); |
| 12 | volatile long double ld_snan = __builtin_nansl(""); |
| 13 | |
| 14 | int issignaling_f(float x) |
| 15 | { |
| 16 | union { float f; uint32_t u; } u = { .f = x }; |
| 17 | return (u.u & 0x7fffffff) > 0x7f800000 && (u.u & 0x400000) == 0; |
| 18 | } |
| 19 | |
| 20 | int issignaling_d(double x) |
| 21 | { |
| 22 | union { double d; uint64_t u; } u = { .d = x }; |
| 23 | return (((u.u & UINT64_C(0x7fffffffffffffff)) > |
| 24 | UINT64_C(0x7ff0000000000000)) && |
| 25 | (u.u & UINT64_C(0x8000000000000)) == 0); |
| 26 | } |
| 27 | |
| 28 | int issignaling_ld(long double x) |
| 29 | { |
| 30 | union { |
| 31 | long double ld; |
| 32 | struct { uint64_t sig; uint16_t sign_exp; } s; |
| 33 | } u = { .ld = x }; |
| 34 | return ((u.s.sign_exp & 0x7fff) == 0x7fff && |
| 35 | (u.s.sig >> 63) != 0 && |
| 36 | (u.s.sig & UINT64_C(0x4000000000000000)) == 0); |
| 37 | } |
| 38 | |
| 39 | int main(void) |
| 40 | { |
| 41 | int ret = 0; |
| 42 | ld_res = f_snan; |
| 43 | if (issignaling_ld(ld_res)) { |
| 44 | printf("FAIL: float -> long double\n"); |
| 45 | ret = 1; |
| 46 | } |
| 47 | ld_res = d_snan; |
| 48 | if (issignaling_ld(ld_res)) { |
| 49 | printf("FAIL: double -> long double\n"); |
| 50 | ret = 1; |
| 51 | } |
| 52 | f_res = ld_snan; |
| 53 | if (issignaling_d(f_res)) { |
| 54 | printf("FAIL: long double -> float\n"); |
| 55 | ret = 1; |
| 56 | } |
| 57 | d_res = ld_snan; |
| 58 | if (issignaling_d(d_res)) { |
| 59 | printf("FAIL: long double -> double\n"); |
| 60 | ret = 1; |
| 61 | } |
| 62 | return ret; |
| 63 | } |