This source file includes following definitions.
- FUNC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21
22 #ifdef USE_LONG_DOUBLE
23
24 extern int rpl_isnanl (long double x) _GL_ATTRIBUTE_CONST;
25 #elif ! defined USE_FLOAT
26
27 extern int rpl_isnand (double x);
28 #else
29
30 extern int rpl_isnanf (float x);
31 #endif
32
33 #include <float.h>
34 #include <string.h>
35
36 #include "float+.h"
37
38 #ifdef USE_LONG_DOUBLE
39 # define FUNC rpl_isnanl
40 # define DOUBLE long double
41 # define MAX_EXP LDBL_MAX_EXP
42 # define MIN_EXP LDBL_MIN_EXP
43 # if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
44 # define KNOWN_EXPBIT0_LOCATION
45 # define EXPBIT0_WORD LDBL_EXPBIT0_WORD
46 # define EXPBIT0_BIT LDBL_EXPBIT0_BIT
47 # endif
48 # define SIZE SIZEOF_LDBL
49 # define L_(literal) literal##L
50 #elif ! defined USE_FLOAT
51 # define FUNC rpl_isnand
52 # define DOUBLE double
53 # define MAX_EXP DBL_MAX_EXP
54 # define MIN_EXP DBL_MIN_EXP
55 # if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
56 # define KNOWN_EXPBIT0_LOCATION
57 # define EXPBIT0_WORD DBL_EXPBIT0_WORD
58 # define EXPBIT0_BIT DBL_EXPBIT0_BIT
59 # endif
60 # define SIZE SIZEOF_DBL
61 # define L_(literal) literal
62 #else
63 # define FUNC rpl_isnanf
64 # define DOUBLE float
65 # define MAX_EXP FLT_MAX_EXP
66 # define MIN_EXP FLT_MIN_EXP
67 # if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
68 # define KNOWN_EXPBIT0_LOCATION
69 # define EXPBIT0_WORD FLT_EXPBIT0_WORD
70 # define EXPBIT0_BIT FLT_EXPBIT0_BIT
71 # endif
72 # define SIZE SIZEOF_FLT
73 # define L_(literal) literal##f
74 #endif
75
76 #define EXP_MASK ((MAX_EXP - MIN_EXP) | 7)
77
78 #define NWORDS \
79 ((sizeof (DOUBLE) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
80 typedef union { DOUBLE value; unsigned int word[NWORDS]; } memory_double;
81
82
83
84
85
86
87
88
89
90 #define IEEE_FLOATING_POINT (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
91 && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
92
93 int
94 FUNC (DOUBLE x)
95 {
96 #if defined KNOWN_EXPBIT0_LOCATION && IEEE_FLOATING_POINT
97 # if defined USE_LONG_DOUBLE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
98
99
100
101
102
103
104
105
106 memory_double m;
107 unsigned int exponent;
108
109 m.value = x;
110 exponent = (m.word[EXPBIT0_WORD] >> EXPBIT0_BIT) & EXP_MASK;
111 # ifdef WORDS_BIGENDIAN
112
113 if (exponent == 0)
114 return 1 & (m.word[0] >> 15);
115 else if (exponent == EXP_MASK)
116 return (((m.word[0] ^ 0x8000U) << 16) | m.word[1] | (m.word[2] >> 16)) != 0;
117 else
118 return 1 & ~(m.word[0] >> 15);
119 # else
120
121 if (exponent == 0)
122 return (m.word[1] >> 31);
123 else if (exponent == EXP_MASK)
124 return ((m.word[1] ^ 0x80000000U) | m.word[0]) != 0;
125 else
126 return (m.word[1] >> 31) ^ 1;
127 # endif
128 # else
129
130
131 # if defined __SUNPRO_C || defined __ICC || defined _MSC_VER \
132 || defined __DECC || defined __TINYC__ \
133 || (defined __sgi && !defined __GNUC__)
134
135
136
137
138
139
140
141 static DOUBLE zero = L_(0.0);
142 memory_double nan;
143 DOUBLE plus_inf = L_(1.0) / zero;
144 DOUBLE minus_inf = -L_(1.0) / zero;
145 nan.value = zero / zero;
146 # else
147 static memory_double nan = { L_(0.0) / L_(0.0) };
148 static DOUBLE plus_inf = L_(1.0) / L_(0.0);
149 static DOUBLE minus_inf = -L_(1.0) / L_(0.0);
150 # endif
151 {
152 memory_double m;
153
154
155
156 m.value = x;
157 if (((m.word[EXPBIT0_WORD] ^ nan.word[EXPBIT0_WORD])
158 & (EXP_MASK << EXPBIT0_BIT))
159 == 0)
160 return (memcmp (&m.value, &plus_inf, SIZE) != 0
161 && memcmp (&m.value, &minus_inf, SIZE) != 0);
162 else
163 return 0;
164 }
165 # endif
166 #else
167
168
169
170 if (x == x)
171 {
172 # if defined USE_LONG_DOUBLE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
173
174 memory_double m1;
175 memory_double m2;
176
177 memset (&m1.value, 0, SIZE);
178 memset (&m2.value, 0, SIZE);
179 m1.value = x;
180 m2.value = x + (x ? 0.0L : -0.0L);
181 if (memcmp (&m1.value, &m2.value, SIZE) != 0)
182 return 1;
183 # endif
184 return 0;
185 }
186 else
187 return 1;
188 #endif
189 }