1 /* -----------------------------------------------------------------------------
3 * (c) Lennart Augustsson
4 * (c) The GHC Team, 1998-2000
6 * Miscellaneous support for floating-point primitives
8 * ---------------------------------------------------------------------------*/
11 #include "Rts.h" // XXX wrong (for IEEE_FLOATING_POINT and WORDS_BIGENDIAN)
13 #define IEEE_FLOATING_POINT 1
21 unsigned int negative:1;
22 unsigned int exponent:8;
23 unsigned int mantissa:23;
25 unsigned int mantissa:23;
26 unsigned int exponent:8;
27 unsigned int negative:1;
33 unsigned int negative:1;
34 unsigned int exponent:8;
35 unsigned int quiet_nan:1;
36 unsigned int mantissa:22;
38 unsigned int mantissa:22;
39 unsigned int quiet_nan:1;
40 unsigned int exponent:8;
41 unsigned int negative:1;
48 To recap, here's the representation of a double precision
49 IEEE floating point number:
51 sign 63 sign bit (0==positive, 1==negative)
52 exponent 62-52 exponent (biased by 1023)
53 fraction 51-0 fraction (bits to right of binary point)
62 unsigned int negative:1;
63 unsigned int exponent:11;
64 unsigned int mantissa0:20;
65 unsigned int mantissa1:32;
67 #if FLOAT_WORDS_BIGENDIAN
68 unsigned int mantissa0:20;
69 unsigned int exponent:11;
70 unsigned int negative:1;
71 unsigned int mantissa1:32;
73 unsigned int mantissa1:32;
74 unsigned int mantissa0:20;
75 unsigned int exponent:11;
76 unsigned int negative:1;
80 /* This format makes it easier to see if a NaN is a signalling NaN. */
84 unsigned int negative:1;
85 unsigned int exponent:11;
86 unsigned int quiet_nan:1;
87 unsigned int mantissa0:19;
88 unsigned int mantissa1:32;
90 #if FLOAT_WORDS_BIGENDIAN
91 unsigned int mantissa0:19;
92 unsigned int quiet_nan:1;
93 unsigned int exponent:11;
94 unsigned int negative:1;
95 unsigned int mantissa1:32;
97 unsigned int mantissa1:32;
98 unsigned int mantissa0:19;
99 unsigned int quiet_nan:1;
100 unsigned int exponent:11;
101 unsigned int negative:1;
108 * Predicates for testing for extreme IEEE fp values.
111 /* In case you don't suppport IEEE, you'll just get dummy defs.. */
112 #ifdef IEEE_FLOATING_POINT
115 isDoubleNaN(HsDouble d)
117 union stg_ieee754_dbl u;
122 u.ieee.exponent == 2047 /* 2^11 - 1 */ && /* Is the exponent all ones? */
123 (u.ieee.mantissa0 != 0 || u.ieee.mantissa1 != 0)
124 /* and the mantissa non-zero? */
129 isDoubleInfinite(HsDouble d)
131 union stg_ieee754_dbl u;
135 /* Inf iff exponent is all ones, mantissa all zeros */
137 u.ieee.exponent == 2047 /* 2^11 - 1 */ &&
138 u.ieee.mantissa0 == 0 &&
139 u.ieee.mantissa1 == 0
144 isDoubleDenormalized(HsDouble d)
146 union stg_ieee754_dbl u;
150 /* A (single/double/quad) precision floating point number
153 - mantissa is non-zero.
154 - (don't care about setting of sign bit.)
158 u.ieee.exponent == 0 &&
159 (u.ieee.mantissa0 != 0 ||
160 u.ieee.mantissa1 != 0)
166 isDoubleNegativeZero(HsDouble d)
168 union stg_ieee754_dbl u;
171 /* sign (bit 63) set (only) => negative zero */
174 u.ieee.negative == 1 &&
175 u.ieee.exponent == 0 &&
176 u.ieee.mantissa0 == 0 &&
177 u.ieee.mantissa1 == 0);
180 /* Same tests, this time for HsFloats. */
183 To recap, here's the representation of a single precision
184 IEEE floating point number:
186 sign 31 sign bit (0 == positive, 1 == negative)
187 exponent 30-23 exponent (biased by 127)
188 fraction 22-0 fraction (bits to right of binary point)
193 isFloatNaN(HsFloat f)
195 union stg_ieee754_flt u;
198 /* Floating point NaN iff exponent is all ones, mantissa is
199 non-zero (but see below.) */
201 u.ieee.exponent == 255 /* 2^8 - 1 */ &&
202 u.ieee.mantissa != 0);
206 isFloatInfinite(HsFloat f)
208 union stg_ieee754_flt u;
211 /* A float is Inf iff exponent is max (all ones),
212 and mantissa is min(all zeros.) */
214 u.ieee.exponent == 255 /* 2^8 - 1 */ &&
215 u.ieee.mantissa == 0);
219 isFloatDenormalized(HsFloat f)
221 union stg_ieee754_flt u;
224 /* A (single/double/quad) precision floating point number
227 - mantissa is non-zero.
228 - (don't care about setting of sign bit.)
232 u.ieee.exponent == 0 &&
233 u.ieee.mantissa != 0);
237 isFloatNegativeZero(HsFloat f)
239 union stg_ieee754_flt u;
242 /* sign (bit 31) set (only) => negative zero */
245 u.ieee.exponent == 0 &&
246 u.ieee.mantissa == 0);
249 #else /* ! IEEE_FLOATING_POINT */
251 /* Dummy definitions of predicates - they all return false */
252 HsInt isDoubleNaN(d) HsDouble d; { return 0; }
253 HsInt isDoubleInfinite(d) HsDouble d; { return 0; }
254 HsInt isDoubleDenormalized(d) HsDouble d; { return 0; }
255 HsInt isDoubleNegativeZero(d) HsDouble d; { return 0; }
256 HsInt isFloatNaN(f) HsFloat f; { return 0; }
257 HsInt isFloatInfinite(f) HsFloat f; { return 0; }
258 HsInt isFloatDenormalized(f) HsFloat f; { return 0; }
259 HsInt isFloatNegativeZero(f) HsFloat f; { return 0; }
261 #endif /* ! IEEE_FLOATING_POINT */