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 } 64