blob: ed6d535ce20ec2aabd4b8f30ac2b002fbe2a5b87 [file] [log] [blame]
Joseph Myers7537c2b2020-05-04 23:37:54 +00001/* Test conversions of signaling NaNs to and from long double. */
2
3#include <stdint.h>
4#include <stdio.h>
5
6volatile float f_res;
7volatile double d_res;
8volatile long double ld_res;
9
10volatile float f_snan = __builtin_nansf("");
11volatile double d_snan = __builtin_nans("");
12volatile long double ld_snan = __builtin_nansl("");
13
14int 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
20int 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
28int 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
39int 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}