Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
NO_SIGNALING_NAN.cpp
Go to the documentation of this file.
1// checking for signaling NaN
2
3
25#include "config.h"
26
27#include <stdio.h>
28#include <float.h>
29
30#if !defined (_RWSTD_NO_FENV_H)
31 // [try to] get floating-point exception support
32# include <fenv.h>
33#else
34# include <ieeefp.h>
35#endif // _RWSTD_NO_FENV_H
36
37
38#ifndef _RWSTD_NO_INFINITY
39
40# if defined _RWSTD_DBL_SNAN_BITS
41
42union {
43 char bits[sizeof (double)];
44 double val;
45} snan = { _RWSTD_DBL_SNAN_BITS };
46
47// assignment or initialization should not trap
48static double d = snan.val;
49
50# else // if !defined (_RWSTD_DBL_SNAN_BITS)
51
52double foo ()
53{
54 const int endian = 1;
55
56 // compute infinity (division may trap)
57 double x = 0.0;
58 x = 1.0 / x;
59
60 // turn infinity into a signaling NaN by setting the LSB
61 ((char*)&x)[(sizeof x - 1) * (!!*(char*)&endian)] |= 1;
62
63 return x;
64}
65
66static double d = foo ();
67
68# endif // _RWSTD_DBL_SNAN_BITS
69
70
71#endif // _RWSTD_NO_INFINITY
72
73
74// prevent optimizers from eliminating expressions such as (d == d)
75volatile double *pd = &d;
76
77
78int main ()
79{
80 // floating point operations on SNAN's might trap
81 // if that happens the test will be considered successful
82
83#if defined (FE_DIVBYZERO) || defined (FE_INEXACT) || defined (FE_INVALID) \
84 || defined (FE_OVERFLOW) || defined (FE_UNDERFLOW)
85
86# pragma STDC FENV_ACCESS ON
87
88 const int all = 0
89
90# ifdef FE_ALL_EXCEPT
91 | FE_ALL_EXCEPT |
92# else // if !defined (FE_ALL_EXCEPT)
93
94# ifdef FE_DIVBYZERO
95 | FE_DIVBYZERO |
96# endif // FE_DIVBYZERO
97
98# ifdef FE_INEXACT
99 | FE_INEXACT |
100# endif // FE_INEXACT
101
102# ifdef FE_INVALID
103 | FE_INVALID |
104# endif // FE_INVALID
105
106# ifdef FE_OVERFLOW
107 | FE_OVERFLOW |
108# endif // FE_OVERFLOW
109
110# ifdef FE_UNDERFLOW
111 | FE_UNDERFLOW |
112# endif // FE_UNDERFLOW
113
114# endif // FE_ALL_EXCEPT
115
116 0; // defintion of all
117
118
119 // assume a C99 conforming environment
120 feclearexcept (all);
121
122 d *= d;
123
124 if (fetestexcept (all))
125 return *pd != d; // have a SNAN
126
127 d /= d;
128
129 if (fetestexcept (all))
130 return *pd != d; // have a SNAN
131
132#elif defined (sun) || defined (__sun) || defined (__sun__)
133
134 fpsetsticky (0);
135
136 // any math operation should trap
137 d *= d;
138
139 if (fpgetsticky ())
140 return *pd != d; // have a SNAN
141
142 d /= d;
143
144 if (fpgetsticky ())
145 return *pd != d; // have a SNAN
146
147#endif // sun
148
149 // NEGATIVE test: successful exit status indicates a failure
150 return 0;
151}
#define d
Definition 17.names.cpp:115
#define x
Definition 17.names.cpp:140
#define val
Definition 17.names.cpp:570
endian
Definition INFINITY.cpp:70
double foo()
volatile double * pd
int main()