|
1 /************************************************************************* |
|
2 * |
|
3 * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net> |
|
4 * |
|
5 * Permission to use, copy, modify, and distribute this software for any |
|
6 * purpose with or without fee is hereby granted, provided that the above |
|
7 * copyright notice and this permission notice appear in all copies. |
|
8 * |
|
9 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED |
|
10 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
|
11 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND |
|
12 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. |
|
13 * |
|
14 * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
15 ************************************************************************ |
|
16 * |
|
17 * Functions to handle special quantities in floating-point numbers |
|
18 * (that is, NaNs and infinity). They provide the capability to detect |
|
19 * and fabricate special quantities. |
|
20 * |
|
21 * Although written to be as portable as possible, it can never be |
|
22 * guaranteed to work on all platforms, as not all hardware supports |
|
23 * special quantities. |
|
24 * |
|
25 * The approach used here (approximately) is to: |
|
26 * |
|
27 * 1. Use C99 functionality when available. |
|
28 * 2. Use IEEE 754 bit-patterns if possible. |
|
29 * 3. Use platform-specific techniques. |
|
30 * |
|
31 ************************************************************************/ |
|
32 |
|
33 /* |
|
34 * |
|
35 * o Put all the magic into trio_fpclassify_and_signbit(), and use this from |
|
36 * trio_isnan() etc. |
|
37 */ |
|
38 |
|
39 /************************************************************************* |
|
40 * Include files |
|
41 */ |
|
42 #include "xmlengtriodef.h" |
|
43 #include "xmlengtrionan.h" |
|
44 |
|
45 #include <math.h> |
|
46 #include <string.h> |
|
47 #include <limits.h> |
|
48 |
|
49 |
|
50 #if defined(TRIO_PLATFORM_UNIX) |
|
51 # include <signal.h> |
|
52 #endif |
|
53 #if defined(TRIO_COMPILER_DECC) |
|
54 # if defined(__linux__) |
|
55 # include <cpml.h> |
|
56 # else |
|
57 # include <fp_class.h> |
|
58 # endif |
|
59 #endif |
|
60 #include <assert.h> |
|
61 |
|
62 #if defined(TRIO_DOCUMENTATION) |
|
63 # include "doc/doc_nan.h" |
|
64 #endif |
|
65 /** @addtogroup SpecialQuantities |
|
66 @{ |
|
67 */ |
|
68 |
|
69 /************************************************************************* |
|
70 * Definitions |
|
71 */ |
|
72 |
|
73 #define TRIO_TRUE (1 == 1) |
|
74 #define TRIO_FALSE (0 == 1) |
|
75 |
|
76 /* |
|
77 * We must enable IEEE floating-point on Alpha |
|
78 */ |
|
79 |
|
80 #if defined(__alpha) && !defined(_IEEE_FP) |
|
81 # if defined(TRIO_COMPILER_DECC) |
|
82 # if defined(TRIO_PLATFORM_VMS) |
|
83 # error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE" |
|
84 # else |
|
85 # if !defined(_CFE) |
|
86 # error "Must be compiled with option -ieee" |
|
87 # endif |
|
88 # endif |
|
89 # elif defined(TRIO_COMPILER_GCC) && (defined(__osf__) || defined(__linux__)) |
|
90 # error "Must be compiled with option -mieee" |
|
91 # endif |
|
92 #endif /* __alpha && ! _IEEE_FP */ |
|
93 |
|
94 /* |
|
95 * In ANSI/IEEE 754-1985 64-bits double format numbers have the |
|
96 * following properties (amoungst others) |
|
97 * |
|
98 * o FLT_RADIX == 2: binary encoding |
|
99 * o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used |
|
100 * to indicate special numbers (e.g. NaN and Infinity), so the |
|
101 * maximum exponent is 10 bits wide (2^10 == 1024). |
|
102 * o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because |
|
103 * numbers are normalized the initial binary 1 is represented |
|
104 * implicitly (the so-called "hidden bit"), which leaves us with |
|
105 * the ability to represent 53 bits wide mantissa. |
|
106 */ |
|
107 #if (FLT_RADIX == 2) && (DBL_MAX_EXP == 1024) && (DBL_MANT_DIG == 53) |
|
108 # define USE_IEEE_754 |
|
109 #endif |
|
110 |
|
111 #if defined(__SYMBIAN32__) || defined(WIN32) |
|
112 # define USE_IEEE_754 |
|
113 #endif |
|
114 |
|
115 #ifndef DBL_MAX |
|
116 #define DBL_MAX 1.79769313486231500e+308 |
|
117 #endif |
|
118 #ifndef DBL_MIN |
|
119 #define DBL_MIN 2.22507385850720200e-308 |
|
120 #endif |
|
121 |
|
122 /************************************************************************* |
|
123 * Constants |
|
124 */ |
|
125 |
|
126 #if defined(USE_IEEE_754) |
|
127 |
|
128 /* |
|
129 * Endian-agnostic indexing macro. |
|
130 * |
|
131 * The value of internalEndianMagic, when converted into a 64-bit |
|
132 * integer, becomes 0x0706050403020100 (we could have used a 64-bit |
|
133 * integer value instead of a double, but not all platforms supports |
|
134 * that type). The value is automatically encoded with the correct |
|
135 * endianess by the compiler, which means that we can support any |
|
136 * kind of endianess. The individual bytes are then used as an index |
|
137 * for the IEEE 754 bit-patterns and masks. |
|
138 */ |
|
139 #define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)]) |
|
140 |
|
141 |
|
142 |
|
143 static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275; |
|
144 |
|
145 /* Mask for the exponent */ |
|
146 static TRIO_CONST unsigned char ieee_754_exponent_mask[] = { |
|
147 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
|
148 }; |
|
149 |
|
150 /* Mask for the mantissa */ |
|
151 static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = { |
|
152 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF |
|
153 }; |
|
154 |
|
155 /* Mask for the sign bit */ |
|
156 static TRIO_CONST unsigned char ieee_754_sign_mask[] = { |
|
157 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
|
158 }; |
|
159 |
|
160 /* Bit-pattern for negative zero */ |
|
161 static TRIO_CONST unsigned char ieee_754_negzero_array[] = { |
|
162 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
|
163 }; |
|
164 |
|
165 /* Bit-pattern for infinity */ |
|
166 static TRIO_CONST unsigned char ieee_754_infinity_array[] = { |
|
167 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
|
168 }; |
|
169 |
|
170 /* Bit-pattern for quiet NaN */ |
|
171 static TRIO_CONST unsigned char ieee_754_qnan_array[] = { |
|
172 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
|
173 }; |
|
174 |
|
175 |
|
176 /************************************************************************* |
|
177 * Functions |
|
178 */ |
|
179 |
|
180 /* |
|
181 * trio_make_double |
|
182 */ |
|
183 TRIO_PRIVATE double |
|
184 trio_make_double |
|
185 TRIO_ARGS1((values), |
|
186 TRIO_CONST unsigned char *values) |
|
187 { |
|
188 TRIO_VOLATILE double result; |
|
189 int i; |
|
190 |
|
191 for (i = 0; i < (int)sizeof(double); i++) { |
|
192 ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i]; |
|
193 } |
|
194 return result; |
|
195 } |
|
196 |
|
197 /* |
|
198 * trio_is_special_quantity |
|
199 */ |
|
200 TRIO_PRIVATE int |
|
201 trio_is_special_quantity |
|
202 TRIO_ARGS2((number, has_mantissa), |
|
203 double number, |
|
204 int *has_mantissa) |
|
205 { |
|
206 unsigned int i; |
|
207 unsigned char current; |
|
208 int is_special_quantity = TRIO_TRUE; |
|
209 |
|
210 *has_mantissa = 0; |
|
211 |
|
212 for (i = 0; i < (unsigned int)sizeof(double); i++) { |
|
213 current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]; |
|
214 is_special_quantity |
|
215 &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]); |
|
216 *has_mantissa |= (current & ieee_754_mantissa_mask[i]); |
|
217 } |
|
218 return is_special_quantity; |
|
219 } |
|
220 |
|
221 /* |
|
222 * trio_is_negative |
|
223 */ |
|
224 TRIO_PRIVATE int |
|
225 trio_is_negative |
|
226 TRIO_ARGS1((number), |
|
227 double number) |
|
228 { |
|
229 unsigned int i; |
|
230 int is_negative = TRIO_FALSE; |
|
231 |
|
232 for (i = 0; i < (unsigned int)sizeof(double); i++) { |
|
233 is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)] |
|
234 & ieee_754_sign_mask[i]); |
|
235 } |
|
236 return is_negative; |
|
237 } |
|
238 |
|
239 #endif /* USE_IEEE_754 */ |
|
240 |
|
241 |
|
242 /** |
|
243 Generate negative zero. |
|
244 |
|
245 @return Floating-point representation of negative zero. |
|
246 */ |
|
247 TRIO_PUBLIC double |
|
248 trio_nzero(TRIO_NOARGS) |
|
249 { |
|
250 #if defined(USE_IEEE_754) |
|
251 return trio_make_double(ieee_754_negzero_array); |
|
252 #else |
|
253 TRIO_VOLATILE double zero = 0.0; |
|
254 |
|
255 return -zero; |
|
256 #endif |
|
257 } |
|
258 |
|
259 /** |
|
260 Generate positive infinity. |
|
261 |
|
262 @return Floating-point representation of positive infinity. |
|
263 */ |
|
264 TRIO_PUBLIC double |
|
265 trio_pinf(TRIO_NOARGS) |
|
266 { |
|
267 /* Cache the result */ |
|
268 //FIXIT |
|
269 // static |
|
270 double result = 0.0; |
|
271 |
|
272 if (result == 0.0) { |
|
273 |
|
274 #if defined(INFINITY) && defined(__STDC_IEC_559__) |
|
275 result = (double)INFINITY; |
|
276 |
|
277 #elif defined(USE_IEEE_754) |
|
278 result = trio_make_double(ieee_754_infinity_array); |
|
279 |
|
280 #else |
|
281 /* |
|
282 * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used |
|
283 * as infinity. Otherwise we have to resort to an overflow |
|
284 * operation to generate infinity. |
|
285 */ |
|
286 # if defined(TRIO_PLATFORM_UNIX) |
|
287 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); |
|
288 # endif |
|
289 |
|
290 result = HUGE_VAL; |
|
291 if (HUGE_VAL == DBL_MAX) { |
|
292 /* Force overflow */ |
|
293 result += HUGE_VAL; |
|
294 } |
|
295 |
|
296 # if defined(TRIO_PLATFORM_UNIX) |
|
297 signal(SIGFPE, signal_handler); |
|
298 # endif |
|
299 |
|
300 #endif |
|
301 } |
|
302 return result; |
|
303 } |
|
304 |
|
305 /** |
|
306 Generate negative infinity. |
|
307 |
|
308 @return Floating-point value of negative infinity. |
|
309 */ |
|
310 TRIO_PUBLIC double |
|
311 trio_ninf(TRIO_NOARGS) |
|
312 { |
|
313 //FIXIT |
|
314 //static |
|
315 double result = 0.0; |
|
316 |
|
317 if (result == 0.0) { |
|
318 /* |
|
319 * Negative infinity is calculated by negating positive infinity, |
|
320 * which can be done because it is legal to do calculations on |
|
321 * infinity (for example, 1 / infinity == 0). |
|
322 */ |
|
323 result = -trio_pinf(); |
|
324 } |
|
325 return result; |
|
326 } |
|
327 |
|
328 /** |
|
329 Generate NaN. |
|
330 |
|
331 @return Floating-point representation of NaN. |
|
332 */ |
|
333 TRIO_PUBLIC double |
|
334 trio_nan(TRIO_NOARGS) |
|
335 { |
|
336 /* Cache the result */ |
|
337 //FIXIT |
|
338 //static |
|
339 double result = 0.0; |
|
340 |
|
341 if (result == 0.0) { |
|
342 |
|
343 #if defined(TRIO_COMPILER_SUPPORTS_C99) |
|
344 result = nan(""); |
|
345 |
|
346 #elif defined(NAN) && defined(__STDC_IEC_559__) |
|
347 result = (double)NAN; |
|
348 |
|
349 #elif defined(USE_IEEE_754) |
|
350 result = trio_make_double(ieee_754_qnan_array); |
|
351 |
|
352 #else |
|
353 /* |
|
354 * There are several ways to generate NaN. The one used here is |
|
355 * to divide infinity by infinity. I would have preferred to add |
|
356 * negative infinity to positive infinity, but that yields wrong |
|
357 * result (infinity) on FreeBSD. |
|
358 * |
|
359 * This may fail if the hardware does not support NaN, or if |
|
360 * the Invalid Operation floating-point exception is unmasked. |
|
361 */ |
|
362 # if defined(TRIO_PLATFORM_UNIX) |
|
363 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); |
|
364 # endif |
|
365 |
|
366 result = trio_pinf() / trio_pinf(); |
|
367 |
|
368 # if defined(TRIO_PLATFORM_UNIX) |
|
369 signal(SIGFPE, signal_handler); |
|
370 # endif |
|
371 |
|
372 #endif |
|
373 } |
|
374 return result; |
|
375 } |
|
376 |
|
377 /** |
|
378 Check for NaN. |
|
379 |
|
380 @param number An arbitrary floating-point number. |
|
381 @return Boolean value indicating whether or not the number is a NaN. |
|
382 */ |
|
383 TRIO_PUBLIC int |
|
384 trio_isnan |
|
385 TRIO_ARGS1((number), |
|
386 double number) |
|
387 { |
|
388 #if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \ |
|
389 || defined(TRIO_COMPILER_SUPPORTS_UNIX95) |
|
390 /* |
|
391 * C99 defines isnan() as a macro. UNIX95 defines isnan() as a |
|
392 * function. This function was already present in XPG4, but this |
|
393 * is a bit tricky to detect with compiler defines, so we choose |
|
394 * the conservative approach and only use it for UNIX95. |
|
395 */ |
|
396 return isnan(number); |
|
397 |
|
398 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) |
|
399 /* |
|
400 * Microsoft Visual C++ and Borland C++ Builder have an _isnan() |
|
401 * function. |
|
402 */ |
|
403 return _isnan(number) ? TRIO_TRUE : TRIO_FALSE; |
|
404 |
|
405 #elif defined(USE_IEEE_754) |
|
406 /* |
|
407 * Examine IEEE 754 bit-pattern. A NaN must have a special exponent |
|
408 * pattern, and a non-empty mantissa. |
|
409 */ |
|
410 int has_mantissa; |
|
411 int is_special_quantity; |
|
412 |
|
413 is_special_quantity = trio_is_special_quantity(number, &has_mantissa); |
|
414 |
|
415 return (is_special_quantity && has_mantissa); |
|
416 |
|
417 #else |
|
418 /* |
|
419 * Fallback solution |
|
420 */ |
|
421 int status; |
|
422 double integral, fraction; |
|
423 |
|
424 # if defined(TRIO_PLATFORM_UNIX) |
|
425 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); |
|
426 # endif |
|
427 |
|
428 status = (/* |
|
429 * NaN is the only number which does not compare to itself |
|
430 */ |
|
431 ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) || |
|
432 /* |
|
433 * Fallback solution if NaN compares to NaN |
|
434 */ |
|
435 ((number != 0.0) && |
|
436 (fraction = modf(number, &integral), |
|
437 integral == fraction))); |
|
438 |
|
439 # if defined(TRIO_PLATFORM_UNIX) |
|
440 signal(SIGFPE, signal_handler); |
|
441 # endif |
|
442 |
|
443 return status; |
|
444 |
|
445 #endif |
|
446 } |
|
447 |
|
448 /** |
|
449 Check for infinity. |
|
450 |
|
451 @param number An arbitrary floating-point number. |
|
452 @return 1 if positive infinity, -1 if negative infinity, 0 otherwise. |
|
453 */ |
|
454 TRIO_PUBLIC int |
|
455 trio_isinf |
|
456 TRIO_ARGS1((number), |
|
457 double number) |
|
458 { |
|
459 #if defined(TRIO_COMPILER_DECC) && !defined(__linux__) |
|
460 /* |
|
461 * DECC has an isinf() macro, but it works differently than that |
|
462 * of C99, so we use the fp_class() function instead. |
|
463 */ |
|
464 return ((fp_class(number) == FP_POS_INF) |
|
465 ? 1 |
|
466 : ((fp_class(number) == FP_NEG_INF) ? -1 : 0)); |
|
467 |
|
468 #elif defined(isinf) && !defined(WIN32) |
|
469 /* |
|
470 * C99 defines isinf() as a macro. |
|
471 */ |
|
472 return isinf(number) |
|
473 ? ((number > 0.0) ? 1 : -1) |
|
474 : 0; |
|
475 |
|
476 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) |
|
477 /* |
|
478 * Microsoft Visual C++ and Borland C++ Builder have an _fpclass() |
|
479 * function that can be used to detect infinity. |
|
480 */ |
|
481 return ((_fpclass(number) == _FPCLASS_PINF) |
|
482 ? 1 |
|
483 : ((_fpclass(number) == _FPCLASS_NINF) ? -1 : 0)); |
|
484 |
|
485 #elif defined(USE_IEEE_754) |
|
486 /* |
|
487 * Examine IEEE 754 bit-pattern. Infinity must have a special exponent |
|
488 * pattern, and an empty mantissa. |
|
489 */ |
|
490 int has_mantissa; |
|
491 int is_special_quantity; |
|
492 |
|
493 is_special_quantity = trio_is_special_quantity(number, &has_mantissa); |
|
494 |
|
495 return (is_special_quantity && !has_mantissa) |
|
496 ? ((number < 0.0) ? -1 : 1) |
|
497 : 0; |
|
498 |
|
499 #else |
|
500 /* |
|
501 * Fallback solution. |
|
502 */ |
|
503 int status; |
|
504 |
|
505 # if defined(TRIO_PLATFORM_UNIX) |
|
506 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); |
|
507 # endif |
|
508 |
|
509 double infinity = trio_pinf(); |
|
510 |
|
511 status = ((number == infinity) |
|
512 ? 1 |
|
513 : ((number == -infinity) ? -1 : 0)); |
|
514 |
|
515 # if defined(TRIO_PLATFORM_UNIX) |
|
516 signal(SIGFPE, signal_handler); |
|
517 # endif |
|
518 |
|
519 return status; |
|
520 |
|
521 #endif |
|
522 } |
|
523 |
|
524 #if 0 |
|
525 /* Temporary - this routine is not used anywhere */ |
|
526 /** |
|
527 Check for finity. |
|
528 |
|
529 @param number An arbitrary floating-point number. |
|
530 @return Boolean value indicating whether or not the number is a finite. |
|
531 */ |
|
532 TRIO_PUBLIC int |
|
533 trio_isfinite |
|
534 TRIO_ARGS1((number), |
|
535 double number) |
|
536 { |
|
537 #if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite) |
|
538 /* |
|
539 * C99 defines isfinite() as a macro. |
|
540 */ |
|
541 return isfinite(number); |
|
542 |
|
543 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) |
|
544 /* |
|
545 * Microsoft Visual C++ and Borland C++ Builder use _finite(). |
|
546 */ |
|
547 return _finite(number); |
|
548 |
|
549 #elif defined(USE_IEEE_754) |
|
550 /* |
|
551 * Examine IEEE 754 bit-pattern. For finity we do not care about the |
|
552 * mantissa. |
|
553 */ |
|
554 int dummy; |
|
555 |
|
556 return (! trio_is_special_quantity(number, &dummy)); |
|
557 |
|
558 #else |
|
559 /* |
|
560 * Fallback solution. |
|
561 */ |
|
562 return ((trio_isinf(number) == 0) && (trio_isnan(number) == 0)); |
|
563 |
|
564 #endif |
|
565 } |
|
566 |
|
567 #endif |
|
568 |
|
569 /* |
|
570 * The sign of NaN is always false |
|
571 */ |
|
572 TRIO_PUBLIC int |
|
573 trio_fpclassify_and_signbit |
|
574 TRIO_ARGS2((number, is_negative), |
|
575 double number, |
|
576 int *is_negative) |
|
577 { |
|
578 #if defined(fpclassify) && defined(signbit) |
|
579 /* |
|
580 * C99 defines fpclassify() and signbit() as a macros |
|
581 */ |
|
582 *is_negative = signbit(number); |
|
583 switch (fpclassify(number)) { |
|
584 case FP_NAN: |
|
585 return TRIO_FP_NAN; |
|
586 case FP_INFINITE: |
|
587 return TRIO_FP_INFINITE; |
|
588 case FP_SUBNORMAL: |
|
589 return TRIO_FP_SUBNORMAL; |
|
590 case FP_ZERO: |
|
591 return TRIO_FP_ZERO; |
|
592 default: |
|
593 return TRIO_FP_NORMAL; |
|
594 } |
|
595 |
|
596 #else |
|
597 # if defined(TRIO_COMPILER_DECC) |
|
598 /* |
|
599 * DECC has an fp_class() function. |
|
600 */ |
|
601 # define TRIO_FPCLASSIFY(n) fp_class(n) |
|
602 # define TRIO_QUIET_NAN FP_QNAN |
|
603 # define TRIO_SIGNALLING_NAN FP_SNAN |
|
604 # define TRIO_POSITIVE_INFINITY FP_POS_INF |
|
605 # define TRIO_NEGATIVE_INFINITY FP_NEG_INF |
|
606 # define TRIO_POSITIVE_SUBNORMAL FP_POS_DENORM |
|
607 # define TRIO_NEGATIVE_SUBNORMAL FP_NEG_DENORM |
|
608 # define TRIO_POSITIVE_ZERO FP_POS_ZERO |
|
609 # define TRIO_NEGATIVE_ZERO FP_NEG_ZERO |
|
610 # define TRIO_POSITIVE_NORMAL FP_POS_NORM |
|
611 # define TRIO_NEGATIVE_NORMAL FP_NEG_NORM |
|
612 |
|
613 # elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) |
|
614 /* |
|
615 * Microsoft Visual C++ and Borland C++ Builder have an _fpclass() |
|
616 * function. |
|
617 */ |
|
618 # define TRIO_FPCLASSIFY(n) _fpclass(n) |
|
619 # define TRIO_QUIET_NAN _FPCLASS_QNAN |
|
620 # define TRIO_SIGNALLING_NAN _FPCLASS_SNAN |
|
621 # define TRIO_POSITIVE_INFINITY _FPCLASS_PINF |
|
622 # define TRIO_NEGATIVE_INFINITY _FPCLASS_NINF |
|
623 # define TRIO_POSITIVE_SUBNORMAL _FPCLASS_PD |
|
624 # define TRIO_NEGATIVE_SUBNORMAL _FPCLASS_ND |
|
625 # define TRIO_POSITIVE_ZERO _FPCLASS_PZ |
|
626 # define TRIO_NEGATIVE_ZERO _FPCLASS_NZ |
|
627 # define TRIO_POSITIVE_NORMAL _FPCLASS_PN |
|
628 # define TRIO_NEGATIVE_NORMAL _FPCLASS_NN |
|
629 |
|
630 # elif defined(FP_PLUS_NORM) |
|
631 /* |
|
632 * HP-UX 9.x and 10.x have an fpclassify() function, that is different |
|
633 * from the C99 fpclassify() macro supported on HP-UX 11.x. |
|
634 * |
|
635 * AIX has class() for C, and _class() for C++, which returns the |
|
636 * same values as the HP-UX fpclassify() function. |
|
637 */ |
|
638 # if defined(TRIO_PLATFORM_AIX) |
|
639 # if defined(__cplusplus) |
|
640 # define TRIO_FPCLASSIFY(n) _class(n) |
|
641 # else |
|
642 # define TRIO_FPCLASSIFY(n) class(n) |
|
643 # endif |
|
644 # else |
|
645 # define TRIO_FPCLASSIFY(n) fpclassify(n) |
|
646 # endif |
|
647 # define TRIO_QUIET_NAN FP_QNAN |
|
648 # define TRIO_SIGNALLING_NAN FP_SNAN |
|
649 # define TRIO_POSITIVE_INFINITY FP_PLUS_INF |
|
650 # define TRIO_NEGATIVE_INFINITY FP_MINUS_INF |
|
651 # define TRIO_POSITIVE_SUBNORMAL FP_PLUS_DENORM |
|
652 # define TRIO_NEGATIVE_SUBNORMAL FP_MINUS_DENORM |
|
653 # define TRIO_POSITIVE_ZERO FP_PLUS_ZERO |
|
654 # define TRIO_NEGATIVE_ZERO FP_MINUS_ZERO |
|
655 # define TRIO_POSITIVE_NORMAL FP_PLUS_NORM |
|
656 # define TRIO_NEGATIVE_NORMAL FP_MINUS_NORM |
|
657 # endif |
|
658 |
|
659 # if defined(TRIO_FPCLASSIFY) |
|
660 switch (TRIO_FPCLASSIFY(number)) { |
|
661 case TRIO_QUIET_NAN: |
|
662 case TRIO_SIGNALLING_NAN: |
|
663 *is_negative = TRIO_FALSE; /* NaN has no sign */ |
|
664 return TRIO_FP_NAN; |
|
665 case TRIO_POSITIVE_INFINITY: |
|
666 *is_negative = TRIO_FALSE; |
|
667 return TRIO_FP_INFINITE; |
|
668 case TRIO_NEGATIVE_INFINITY: |
|
669 *is_negative = TRIO_TRUE; |
|
670 return TRIO_FP_INFINITE; |
|
671 case TRIO_POSITIVE_SUBNORMAL: |
|
672 *is_negative = TRIO_FALSE; |
|
673 return TRIO_FP_SUBNORMAL; |
|
674 case TRIO_NEGATIVE_SUBNORMAL: |
|
675 *is_negative = TRIO_TRUE; |
|
676 return TRIO_FP_SUBNORMAL; |
|
677 case TRIO_POSITIVE_ZERO: |
|
678 *is_negative = TRIO_FALSE; |
|
679 return TRIO_FP_ZERO; |
|
680 case TRIO_NEGATIVE_ZERO: |
|
681 *is_negative = TRIO_TRUE; |
|
682 return TRIO_FP_ZERO; |
|
683 case TRIO_POSITIVE_NORMAL: |
|
684 *is_negative = TRIO_FALSE; |
|
685 return TRIO_FP_NORMAL; |
|
686 case TRIO_NEGATIVE_NORMAL: |
|
687 *is_negative = TRIO_TRUE; |
|
688 return TRIO_FP_NORMAL; |
|
689 default: |
|
690 /* Just in case... */ |
|
691 *is_negative = (number < 0.0); |
|
692 return TRIO_FP_NORMAL; |
|
693 } |
|
694 |
|
695 # else |
|
696 /* |
|
697 * Fallback solution. |
|
698 */ |
|
699 int rc; |
|
700 |
|
701 if (number == 0.0) { |
|
702 /* |
|
703 * In IEEE 754 the sign of zero is ignored in comparisons, so we |
|
704 * have to handle this as a special case by examining the sign bit |
|
705 * directly. |
|
706 */ |
|
707 # if defined(USE_IEEE_754) |
|
708 *is_negative = trio_is_negative(number); |
|
709 # else |
|
710 *is_negative = TRIO_FALSE; |
|
711 # endif |
|
712 return TRIO_FP_ZERO; |
|
713 } |
|
714 if (trio_isnan(number)) { |
|
715 *is_negative = TRIO_FALSE; |
|
716 return TRIO_FP_NAN; |
|
717 } |
|
718 rc = trio_isinf(number); |
|
719 if (rc) { |
|
720 *is_negative = (rc == -1); |
|
721 return TRIO_FP_INFINITE; |
|
722 } |
|
723 if ((number > 0.0) && (number < DBL_MIN)) { |
|
724 *is_negative = TRIO_FALSE; |
|
725 return TRIO_FP_SUBNORMAL; |
|
726 } |
|
727 if ((number < 0.0) && (number > -DBL_MIN)) { |
|
728 *is_negative = TRIO_TRUE; |
|
729 return TRIO_FP_SUBNORMAL; |
|
730 } |
|
731 *is_negative = (number < 0.0); |
|
732 return TRIO_FP_NORMAL; |
|
733 |
|
734 # endif |
|
735 #endif |
|
736 } |
|
737 |
|
738 /** |
|
739 Examine the sign of a number. |
|
740 |
|
741 @param number An arbitrary floating-point number. |
|
742 @return Boolean value indicating whether or not the number has the |
|
743 sign bit set (i.e. is negative). |
|
744 */ |
|
745 TRIO_PUBLIC int |
|
746 trio_signbit |
|
747 TRIO_ARGS1((number), |
|
748 double number) |
|
749 { |
|
750 int is_negative; |
|
751 |
|
752 (void)trio_fpclassify_and_signbit(number, &is_negative); |
|
753 return is_negative; |
|
754 } |
|
755 |
|
756 #if 0 |
|
757 /* Temporary - this routine is not used in libxml */ |
|
758 /** |
|
759 Examine the class of a number. |
|
760 |
|
761 @param number An arbitrary floating-point number. |
|
762 @return Enumerable value indicating the class of @p number |
|
763 */ |
|
764 TRIO_PUBLIC int |
|
765 trio_fpclassify |
|
766 TRIO_ARGS1((number), |
|
767 double number) |
|
768 { |
|
769 int dummy; |
|
770 |
|
771 return trio_fpclassify_and_signbit(number, &dummy); |
|
772 } |
|
773 |
|
774 #endif |
|
775 |
|
776 /** @} SpecialQuantities */ |
|
777 |
|
778 /************************************************************************* |
|
779 * For test purposes. |
|
780 * |
|
781 * Add the following compiler option to include this test code. |
|
782 * |
|
783 * Unix : -DSTANDALONE |
|
784 * VMS : /DEFINE=(STANDALONE) |
|
785 */ |
|
786 #if defined(STANDALONE) |
|
787 # include <stdio.h> |
|
788 |
|
789 static TRIO_CONST char * |
|
790 getClassification |
|
791 TRIO_ARGS1((type), |
|
792 int type) |
|
793 { |
|
794 switch (type) { |
|
795 case TRIO_FP_INFINITE: |
|
796 return "FP_INFINITE"; |
|
797 case TRIO_FP_NAN: |
|
798 return "FP_NAN"; |
|
799 case TRIO_FP_NORMAL: |
|
800 return "FP_NORMAL"; |
|
801 case TRIO_FP_SUBNORMAL: |
|
802 return "FP_SUBNORMAL"; |
|
803 case TRIO_FP_ZERO: |
|
804 return "FP_ZERO"; |
|
805 default: |
|
806 return "FP_UNKNOWN"; |
|
807 } |
|
808 } |
|
809 |
|
810 static void |
|
811 print_class |
|
812 TRIO_ARGS2((prefix, number), |
|
813 TRIO_CONST char *prefix, |
|
814 double number) |
|
815 { |
|
816 printf("%-6s: %s %-15s %g\n", |
|
817 prefix, |
|
818 trio_signbit(number) ? "-" : "+", |
|
819 getClassification(TRIO_FPCLASSIFY(number)), |
|
820 number); |
|
821 } |
|
822 |
|
823 |
|
824 int main(TRIO_NOARGS) |
|
825 { |
|
826 double my_nan; |
|
827 double my_pinf; |
|
828 double my_ninf; |
|
829 # if defined(TRIO_PLATFORM_UNIX) |
|
830 void (*signal_handler) TRIO_PROTO((int)); |
|
831 # endif |
|
832 |
|
833 my_nan = trio_nan(); |
|
834 my_pinf = trio_pinf(); |
|
835 my_ninf = trio_ninf(); |
|
836 |
|
837 print_class("Nan", my_nan); |
|
838 print_class("PInf", my_pinf); |
|
839 print_class("NInf", my_ninf); |
|
840 print_class("PZero", 0.0); |
|
841 print_class("NZero", -0.0); |
|
842 print_class("PNorm", 1.0); |
|
843 print_class("NNorm", -1.0); |
|
844 print_class("PSub", 1.01e-307 - 1.00e-307); |
|
845 print_class("NSub", 1.00e-307 - 1.01e-307); |
|
846 |
|
847 printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", |
|
848 my_nan, |
|
849 ((unsigned char *)&my_nan)[0], |
|
850 ((unsigned char *)&my_nan)[1], |
|
851 ((unsigned char *)&my_nan)[2], |
|
852 ((unsigned char *)&my_nan)[3], |
|
853 ((unsigned char *)&my_nan)[4], |
|
854 ((unsigned char *)&my_nan)[5], |
|
855 ((unsigned char *)&my_nan)[6], |
|
856 ((unsigned char *)&my_nan)[7], |
|
857 trio_isnan(my_nan), trio_isinf(my_nan)); |
|
858 printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", |
|
859 my_pinf, |
|
860 ((unsigned char *)&my_pinf)[0], |
|
861 ((unsigned char *)&my_pinf)[1], |
|
862 ((unsigned char *)&my_pinf)[2], |
|
863 ((unsigned char *)&my_pinf)[3], |
|
864 ((unsigned char *)&my_pinf)[4], |
|
865 ((unsigned char *)&my_pinf)[5], |
|
866 ((unsigned char *)&my_pinf)[6], |
|
867 ((unsigned char *)&my_pinf)[7], |
|
868 trio_isnan(my_pinf), trio_isinf(my_pinf)); |
|
869 printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", |
|
870 my_ninf, |
|
871 ((unsigned char *)&my_ninf)[0], |
|
872 ((unsigned char *)&my_ninf)[1], |
|
873 ((unsigned char *)&my_ninf)[2], |
|
874 ((unsigned char *)&my_ninf)[3], |
|
875 ((unsigned char *)&my_ninf)[4], |
|
876 ((unsigned char *)&my_ninf)[5], |
|
877 ((unsigned char *)&my_ninf)[6], |
|
878 ((unsigned char *)&my_ninf)[7], |
|
879 trio_isnan(my_ninf), trio_isinf(my_ninf)); |
|
880 |
|
881 # if defined(TRIO_PLATFORM_UNIX) |
|
882 signal_handler = signal(SIGFPE, SIG_IGN); |
|
883 # endif |
|
884 |
|
885 my_pinf = DBL_MAX + DBL_MAX; |
|
886 my_ninf = -my_pinf; |
|
887 my_nan = my_pinf / my_pinf; |
|
888 |
|
889 # if defined(TRIO_PLATFORM_UNIX) |
|
890 signal(SIGFPE, signal_handler); |
|
891 # endif |
|
892 |
|
893 printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", |
|
894 my_nan, |
|
895 ((unsigned char *)&my_nan)[0], |
|
896 ((unsigned char *)&my_nan)[1], |
|
897 ((unsigned char *)&my_nan)[2], |
|
898 ((unsigned char *)&my_nan)[3], |
|
899 ((unsigned char *)&my_nan)[4], |
|
900 ((unsigned char *)&my_nan)[5], |
|
901 ((unsigned char *)&my_nan)[6], |
|
902 ((unsigned char *)&my_nan)[7], |
|
903 trio_isnan(my_nan), trio_isinf(my_nan)); |
|
904 printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", |
|
905 my_pinf, |
|
906 ((unsigned char *)&my_pinf)[0], |
|
907 ((unsigned char *)&my_pinf)[1], |
|
908 ((unsigned char *)&my_pinf)[2], |
|
909 ((unsigned char *)&my_pinf)[3], |
|
910 ((unsigned char *)&my_pinf)[4], |
|
911 ((unsigned char *)&my_pinf)[5], |
|
912 ((unsigned char *)&my_pinf)[6], |
|
913 ((unsigned char *)&my_pinf)[7], |
|
914 trio_isnan(my_pinf), trio_isinf(my_pinf)); |
|
915 printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", |
|
916 my_ninf, |
|
917 ((unsigned char *)&my_ninf)[0], |
|
918 ((unsigned char *)&my_ninf)[1], |
|
919 ((unsigned char *)&my_ninf)[2], |
|
920 ((unsigned char *)&my_ninf)[3], |
|
921 ((unsigned char *)&my_ninf)[4], |
|
922 ((unsigned char *)&my_ninf)[5], |
|
923 ((unsigned char *)&my_ninf)[6], |
|
924 ((unsigned char *)&my_ninf)[7], |
|
925 trio_isnan(my_ninf), trio_isinf(my_ninf)); |
|
926 |
|
927 return 0; |
|
928 } |
|
929 #endif |
|
930 |