Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/psx/mednadisc/trio/trionan.c
2 views
1
/*************************************************************************
2
*
3
* $Id$
4
*
5
* Copyright (C) 2001 Bjorn Reese <[email protected]>
6
*
7
* Permission to use, copy, modify, and distribute this software for any
8
* purpose with or without fee is hereby granted, provided that the above
9
* copyright notice and this permission notice appear in all copies.
10
*
11
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14
* CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15
*
16
************************************************************************
17
*
18
* Functions to handle special quantities in floating-point numbers
19
* (that is, NaNs and infinity). They provide the capability to detect
20
* and fabricate special quantities.
21
*
22
* Although written to be as portable as possible, it can never be
23
* guaranteed to work on all platforms, as not all hardware supports
24
* special quantities.
25
*
26
* The approach used here (approximately) is to:
27
*
28
* 1. Use C99 functionality when available.
29
* 2. Use IEEE 754 bit-patterns if possible.
30
* 3. Use platform-specific techniques.
31
*
32
************************************************************************/
33
34
/*************************************************************************
35
* Include files
36
*/
37
#include "triodef.h"
38
#include "trionan.h"
39
40
#include <math.h>
41
#include <string.h>
42
#include <limits.h>
43
#if !defined(TRIO_PLATFORM_SYMBIAN)
44
# include <float.h>
45
#endif
46
#if defined(TRIO_PLATFORM_UNIX)
47
# include <signal.h>
48
#endif
49
#if defined(TRIO_COMPILER_DECC)
50
# include <fp_class.h>
51
#endif
52
#include <assert.h>
53
54
#if defined(TRIO_DOCUMENTATION)
55
# include "doc/doc_nan.h"
56
#endif
57
/** @addtogroup SpecialQuantities
58
@{
59
*/
60
61
/*************************************************************************
62
* Definitions
63
*/
64
65
#if !defined(TRIO_PUBLIC_NAN)
66
# define TRIO_PUBLIC_NAN TRIO_PUBLIC
67
#endif
68
#if !defined(TRIO_PRIVATE_NAN)
69
# define TRIO_PRIVATE_NAN TRIO_PRIVATE
70
#endif
71
72
#define TRIO_TRUE (1 == 1)
73
#define TRIO_FALSE (0 == 1)
74
75
/*
76
* We must enable IEEE floating-point on Alpha
77
*/
78
#if defined(__alpha) && !defined(_IEEE_FP)
79
# if defined(TRIO_COMPILER_DECC)
80
# if defined(TRIO_PLATFORM_VMS)
81
# error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE"
82
# else
83
# if !defined(_CFE)
84
# error "Must be compiled with option -ieee"
85
# endif
86
# endif
87
# else
88
# if defined(TRIO_COMPILER_GCC)
89
# error "Must be compiled with option -mieee"
90
# endif
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 defined(__STDC_IEC_559__)
108
# define TRIO_IEEE_754
109
#else
110
# if (FLT_RADIX - 0 == 2) && (DBL_MAX_EXP - 0 == 1024) && (DBL_MANT_DIG - 0 == 53)
111
# define TRIO_IEEE_754
112
# endif
113
#endif
114
115
/*
116
* Determine which fpclassify_and_sign() function to use.
117
*/
118
#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
119
# if defined(PREDEF_STANDARD_C99) && defined(fpclassify)
120
# define TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT
121
# else
122
# if defined(TRIO_COMPILER_DECC)
123
# define TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT
124
# else
125
# if defined(TRIO_COMPILER_VISUALC) || defined(TRIO_COMPILER_BORLAND)
126
# define TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT
127
# else
128
# if defined(TRIO_COMPILER_HP) && defined(FP_PLUS_NORM)
129
# define TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT
130
# else
131
# if defined(TRIO_COMPILER_XLC) && defined(FP_PLUS_NORM)
132
# define TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT
133
# else
134
# define TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT
135
# endif
136
# endif
137
# endif
138
# endif
139
# endif
140
#endif
141
142
/*
143
* Determine how to generate negative zero.
144
*/
145
#if defined(TRIO_FUNC_NZERO)
146
# if defined(TRIO_IEEE_754)
147
# define TRIO_NZERO_IEEE_754
148
# else
149
# define TRIO_NZERO_FALLBACK
150
# endif
151
#endif
152
153
/*
154
* Determine how to generate positive infinity.
155
*/
156
#if defined(TRIO_FUNC_PINF)
157
# if defined(INFINITY) && defined(__STDC_IEC_559__)
158
# define TRIO_PINF_C99_MACRO
159
# else
160
# if defined(TRIO_IEEE_754)
161
# define TRIO_PINF_IEEE_754
162
# else
163
# define TRIO_PINF_FALLBACK
164
# endif
165
# endif
166
#endif
167
168
/*
169
* Determine how to generate NaN.
170
*/
171
#if defined(TRIO_FUNC_NAN)
172
# if defined(PREDEF_STANDARD_C99) && !defined(TRIO_COMPILER_DECC)
173
# define TRIO_NAN_C99_FUNCTION
174
# else
175
# if defined(NAN) && defined(__STDC_IEC_559__)
176
# define TRIO_NAN_C99_MACRO
177
# else
178
# if defined(TRIO_IEEE_754)
179
# define TRIO_NAN_IEEE_754
180
# else
181
# define TRIO_NAN_FALLBACK
182
# endif
183
# endif
184
# endif
185
#endif
186
187
/*
188
* Resolve internal dependencies.
189
*/
190
#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)
191
# define TRIO_FUNC_INTERNAL_ISNAN
192
# define TRIO_FUNC_INTERNAL_ISINF
193
# if defined(TRIO_IEEE_754)
194
# define TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY
195
# define TRIO_FUNC_INTERNAL_IS_NEGATIVE
196
# endif
197
#endif
198
199
#if defined(TRIO_NZERO_IEEE_754) \
200
|| defined(TRIO_PINF_IEEE_754) \
201
|| defined(TRIO_NAN_IEEE_754)
202
# define TRIO_FUNC_INTERNAL_MAKE_DOUBLE
203
#endif
204
205
#if defined(TRIO_FUNC_INTERNAL_ISNAN)
206
# if defined(PREDEF_STANDARD_XPG3)
207
# define TRIO_INTERNAL_ISNAN_XPG3
208
# else
209
# if defined(TRIO_IEEE_754)
210
# define TRIO_INTERNAL_ISNAN_IEEE_754
211
# else
212
# define TRIO_INTERNAL_ISNAN_FALLBACK
213
# endif
214
# endif
215
#endif
216
217
#if defined(TRIO_FUNC_INTERNAL_ISINF)
218
# if defined(TRIO_IEEE_754)
219
# define TRIO_INTERNAL_ISINF_IEEE_754
220
# else
221
# define TRIO_INTERNAL_ISINF_FALLBACK
222
# endif
223
#endif
224
225
/*************************************************************************
226
* Constants
227
*/
228
229
#if !defined(TRIO_EMBED_NAN)
230
static TRIO_CONST char rcsid[] = "@(#)$Id$";
231
#endif
232
233
#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE) \
234
|| defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY) \
235
|| defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
236
/*
237
* Endian-agnostic indexing macro.
238
*
239
* The value of internalEndianMagic, when converted into a 64-bit
240
* integer, becomes 0x0706050403020100 (we could have used a 64-bit
241
* integer value instead of a double, but not all platforms supports
242
* that type). The value is automatically encoded with the correct
243
* endianess by the compiler, which means that we can support any
244
* kind of endianess. The individual bytes are then used as an index
245
* for the IEEE 754 bit-patterns and masks.
246
*/
247
#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
248
static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
249
#endif
250
251
#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)
252
/* Mask for the exponent */
253
static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
254
0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
255
};
256
257
/* Mask for the mantissa */
258
static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {
259
0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
260
};
261
#endif
262
263
#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
264
/* Mask for the sign bit */
265
static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
266
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
267
};
268
#endif
269
270
#if defined(TRIO_NZERO_IEEE_754)
271
/* Bit-pattern for negative zero */
272
static TRIO_CONST unsigned char ieee_754_negzero_array[] = {
273
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
274
};
275
#endif
276
277
#if defined(TRIO_PINF_IEEE_754)
278
/* Bit-pattern for infinity */
279
static TRIO_CONST unsigned char ieee_754_infinity_array[] = {
280
0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
281
};
282
#endif
283
284
#if defined(TRIO_NAN_IEEE_754)
285
/* Bit-pattern for quiet NaN */
286
static TRIO_CONST unsigned char ieee_754_qnan_array[] = {
287
0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
288
};
289
#endif
290
291
292
/*************************************************************************
293
* Internal functions
294
*/
295
296
/*
297
*
298
*/
299
#if defined(TRIO_PLATFORM_UNIX) && defined(TRIO_INTERNAL_ISNAN_FALLBACK)
300
301
/* Assume that if SA_SIGINFO is defined, then sigaction() and
302
* 'struct sigaction' are also properly defined on this platform.
303
*/
304
#ifndef TRIO_USE_SIGACTION
305
# ifdef SA_SIGINFO
306
# define TRIO_USE_SIGACTION 1
307
# else
308
# define TRIO_USE_SIGACTION 0
309
# endif
310
#endif
311
312
# if TRIO_USE_SIGACTION
313
typedef struct sigaction signal_handler_t;
314
# else
315
typedef void (*signal_handler_t) TRIO_PROTO((int));
316
# endif
317
318
/*
319
* internal_ignore_signal_handler
320
*/
321
322
TRIO_PRIVATE_NAN signal_handler_t
323
internal_ignore_signal_handler
324
TRIO_ARGS1((signum),
325
int signum)
326
{
327
# if TRIO_USE_SIGACTION
328
signal_handler_t old_handler, new_handler;
329
memset(&new_handler, '\0', sizeof(new_handler));
330
new_handler.sa_handler = SIG_IGN;
331
new_handler.sa_flags = SA_RESTART;
332
sigaction(signum, &new_handler, &old_handler);
333
return old_handler;
334
# else
335
return signal(signum, SIG_IGN);
336
# endif
337
}
338
339
/*
340
* internal_restore_signal_handler
341
*/
342
TRIO_PRIVATE_NAN void
343
internal_restore_signal_handler
344
TRIO_ARGS2((signum, handler),
345
int signum,
346
signal_handler_t handler)
347
{
348
# if TRIO_USE_SIGACTION
349
sigaction(signum, &handler, NULL);
350
# else
351
signal(signum, handler);
352
# endif
353
}
354
355
#endif
356
357
/*
358
* internal_make_double
359
*/
360
#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE)
361
362
TRIO_PRIVATE_NAN double
363
internal_make_double
364
TRIO_ARGS1((values),
365
TRIO_CONST unsigned char *values)
366
{
367
TRIO_VOLATILE double result;
368
int i;
369
370
for (i = 0; i < (int)sizeof(double); i++) {
371
((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i];
372
}
373
return result;
374
}
375
376
#endif
377
378
/*
379
* internal_is_special_quantity
380
*/
381
#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)
382
383
TRIO_PRIVATE_NAN int
384
internal_is_special_quantity
385
TRIO_ARGS2((number, has_mantissa),
386
double number,
387
int *has_mantissa)
388
{
389
unsigned int i;
390
unsigned char current;
391
int is_special_quantity = TRIO_TRUE;
392
393
*has_mantissa = 0;
394
395
for (i = 0; i < (unsigned int)sizeof(double); i++) {
396
current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];
397
is_special_quantity
398
&= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]);
399
*has_mantissa |= (current & ieee_754_mantissa_mask[i]);
400
}
401
return is_special_quantity;
402
}
403
404
#endif
405
406
/*
407
* internal_is_negative
408
*/
409
#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
410
411
TRIO_PRIVATE_NAN int
412
internal_is_negative
413
TRIO_ARGS1((number),
414
double number)
415
{
416
unsigned int i;
417
int is_negative = TRIO_FALSE;
418
419
for (i = 0; i < (unsigned int)sizeof(double); i++) {
420
is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]
421
& ieee_754_sign_mask[i]);
422
}
423
return is_negative;
424
}
425
426
#endif
427
428
#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)
429
430
TRIO_PRIVATE_NAN TRIO_INLINE int
431
c99_fpclassify_and_signbit
432
TRIO_ARGS2((number, is_negative),
433
double number,
434
int *is_negative)
435
{
436
*is_negative = signbit(number);
437
switch (fpclassify(number)) {
438
case FP_NAN:
439
return TRIO_FP_NAN;
440
case FP_INFINITE:
441
return TRIO_FP_INFINITE;
442
case FP_SUBNORMAL:
443
return TRIO_FP_SUBNORMAL;
444
case FP_ZERO:
445
return TRIO_FP_ZERO;
446
default:
447
return TRIO_FP_NORMAL;
448
}
449
}
450
451
#endif /* TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT */
452
453
#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)
454
455
TRIO_PRIVATE_NAN TRIO_INLINE int
456
decc_fpclassify_and_signbit
457
TRIO_ARGS2((number, is_negative),
458
double number,
459
int *is_negative)
460
{
461
switch (fp_class(number)) {
462
case FP_QNAN:
463
case FP_SNAN:
464
*is_negative = TRIO_FALSE; /* NaN has no sign */
465
return TRIO_FP_NAN;
466
case FP_POS_INF:
467
*is_negative = TRIO_FALSE;
468
return TRIO_FP_INFINITE;
469
case FP_NEG_INF:
470
*is_negative = TRIO_TRUE;
471
return TRIO_FP_INFINITE;
472
case FP_POS_DENORM:
473
*is_negative = TRIO_FALSE;
474
return TRIO_FP_SUBNORMAL;
475
case FP_NEG_DENORM:
476
*is_negative = TRIO_TRUE;
477
return TRIO_FP_SUBNORMAL;
478
case FP_POS_ZERO:
479
*is_negative = TRIO_FALSE;
480
return TRIO_FP_ZERO;
481
case FP_NEG_ZERO:
482
*is_negative = TRIO_TRUE;
483
return TRIO_FP_ZERO;
484
case FP_POS_NORM:
485
*is_negative = TRIO_FALSE;
486
return TRIO_FP_NORMAL;
487
case FP_NEG_NORM:
488
*is_negative = TRIO_TRUE;
489
return TRIO_FP_NORMAL;
490
default:
491
*is_negative = (number < 0.0);
492
return TRIO_FP_NORMAL;
493
}
494
}
495
496
#endif /* TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT */
497
498
#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)
499
500
TRIO_PRIVATE_NAN int
501
ms_fpclassify_and_signbit
502
TRIO_ARGS2((number, is_negative),
503
double number,
504
int *is_negative)
505
{
506
int result;
507
# if defined(TRIO_COMPILER_BORLAND)
508
/*
509
* The floating-point precision may be changed by the Borland _fpclass()
510
* function, so we have to save and restore the floating-point control mask.
511
*/
512
unsigned int mask;
513
/* Remember the old mask */
514
mask = _control87(0, 0);
515
# endif
516
517
switch (_fpclass(number)) {
518
case _FPCLASS_QNAN:
519
case _FPCLASS_SNAN:
520
*is_negative = TRIO_FALSE; /* NaN has no sign */
521
result = TRIO_FP_NAN;
522
break;
523
case _FPCLASS_PINF:
524
*is_negative = TRIO_FALSE;
525
result = TRIO_FP_INFINITE;
526
break;
527
case _FPCLASS_NINF:
528
*is_negative = TRIO_TRUE;
529
result = TRIO_FP_INFINITE;
530
break;
531
case _FPCLASS_PD:
532
*is_negative = TRIO_FALSE;
533
result = TRIO_FP_SUBNORMAL;
534
break;
535
case _FPCLASS_ND:
536
*is_negative = TRIO_TRUE;
537
result = TRIO_FP_SUBNORMAL;
538
break;
539
case _FPCLASS_PZ:
540
*is_negative = TRIO_FALSE;
541
result = TRIO_FP_ZERO;
542
break;
543
case _FPCLASS_NZ:
544
*is_negative = TRIO_TRUE;
545
result = TRIO_FP_ZERO;
546
break;
547
case _FPCLASS_PN:
548
*is_negative = TRIO_FALSE;
549
result = TRIO_FP_NORMAL;
550
break;
551
case _FPCLASS_NN:
552
*is_negative = TRIO_TRUE;
553
result = TRIO_FP_NORMAL;
554
break;
555
default:
556
*is_negative = (number < 0.0);
557
result = TRIO_FP_NORMAL;
558
break;
559
}
560
561
# if defined(TRIO_COMPILER_BORLAND)
562
/* Restore the old precision */
563
(void)_control87(mask, MCW_PC);
564
# endif
565
566
return result;
567
}
568
569
#endif /* TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT */
570
571
#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)
572
573
TRIO_PRIVATE_NAN TRIO_INLINE int
574
hp_fpclassify_and_signbit
575
TRIO_ARGS2((number, is_negative),
576
double number,
577
int *is_negative)
578
{
579
/*
580
* HP-UX 9.x and 10.x have an fpclassify() function, that is different
581
* from the C99 fpclassify() macro supported on HP-UX 11.x.
582
*/
583
switch (fpclassify(number)) {
584
case FP_QNAN:
585
case FP_SNAN:
586
*is_negative = TRIO_FALSE; /* NaN has no sign */
587
return TRIO_FP_NAN;
588
case FP_PLUS_INF:
589
*is_negative = TRIO_FALSE;
590
return TRIO_FP_INFINITE;
591
case FP_MINUS_INF:
592
*is_negative = TRIO_TRUE;
593
return TRIO_FP_INFINITE;
594
case FP_PLUS_DENORM:
595
*is_negative = TRIO_FALSE;
596
return TRIO_FP_SUBNORMAL;
597
case FP_MINUS_DENORM:
598
*is_negative = TRIO_TRUE;
599
return TRIO_FP_SUBNORMAL;
600
case FP_PLUS_ZERO:
601
*is_negative = TRIO_FALSE;
602
return TRIO_FP_ZERO;
603
case FP_MINUS_ZERO:
604
*is_negative = TRIO_TRUE;
605
return TRIO_FP_ZERO;
606
case FP_PLUS_NORM:
607
*is_negative = TRIO_FALSE;
608
return TRIO_FP_NORMAL;
609
case FP_MINUS_NORM:
610
*is_negative = TRIO_TRUE;
611
return TRIO_FP_NORMAL;
612
default:
613
*is_negative = (number < 0.0);
614
return TRIO_FP_NORMAL;
615
}
616
}
617
618
#endif /* TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT */
619
620
#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)
621
622
TRIO_PRIVATE_NAN TRIO_INLINE int
623
xlc_fpclassify_and_signbit
624
TRIO_ARGS2((number, is_negative),
625
double number,
626
int *is_negative)
627
{
628
/*
629
* AIX has class() for C, and _class() for C++
630
*/
631
# if defined(__cplusplus)
632
# define AIX_CLASS(n) _class(n)
633
# else
634
# define AIX_CLASS(n) class(n)
635
# endif
636
637
switch (AIX_CLASS(number)) {
638
case FP_QNAN:
639
case FP_SNAN:
640
*is_negative = TRIO_FALSE; /* NaN has no sign */
641
return TRIO_FP_NAN;
642
case FP_PLUS_INF:
643
*is_negative = TRIO_FALSE;
644
return TRIO_FP_INFINITE;
645
case FP_MINUS_INF:
646
*is_negative = TRIO_TRUE;
647
return TRIO_FP_INFINITE;
648
case FP_PLUS_DENORM:
649
*is_negative = TRIO_FALSE;
650
return TRIO_FP_SUBNORMAL;
651
case FP_MINUS_DENORM:
652
*is_negative = TRIO_TRUE;
653
return TRIO_FP_SUBNORMAL;
654
case FP_PLUS_ZERO:
655
*is_negative = TRIO_FALSE;
656
return TRIO_FP_ZERO;
657
case FP_MINUS_ZERO:
658
*is_negative = TRIO_TRUE;
659
return TRIO_FP_ZERO;
660
case FP_PLUS_NORM:
661
*is_negative = TRIO_FALSE;
662
return TRIO_FP_NORMAL;
663
case FP_MINUS_NORM:
664
*is_negative = TRIO_TRUE;
665
return TRIO_FP_NORMAL;
666
default:
667
*is_negative = (number < 0.0);
668
return TRIO_FP_NORMAL;
669
}
670
}
671
672
#endif /* TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT */
673
674
#if defined(TRIO_FUNC_INTERNAL_ISNAN)
675
676
TRIO_PRIVATE_NAN TRIO_INLINE int
677
internal_isnan
678
TRIO_ARGS1((number),
679
double number)
680
{
681
# if defined(TRIO_INTERNAL_ISNAN_XPG3) || defined(TRIO_PLATFORM_SYMBIAN)
682
/*
683
* XPG3 defines isnan() as a function.
684
*/
685
return isnan(number);
686
687
# endif
688
689
# if defined(TRIO_INTERNAL_ISNAN_IEEE_754)
690
691
/*
692
* Examine IEEE 754 bit-pattern. A NaN must have a special exponent
693
* pattern, and a non-empty mantissa.
694
*/
695
int has_mantissa;
696
int is_special_quantity;
697
698
is_special_quantity = internal_is_special_quantity(number, &has_mantissa);
699
700
return (is_special_quantity && has_mantissa);
701
702
# endif
703
704
# if defined(TRIO_INTERNAL_ISNAN_FALLBACK)
705
706
/*
707
* Fallback solution
708
*/
709
int status;
710
double integral, fraction;
711
712
# if defined(TRIO_PLATFORM_UNIX)
713
signal_handler_t sigfpe_handler = internal_ignore_signal_handler(SIGFPE);
714
# endif
715
716
status = (/*
717
* NaN is the only number which does not compare to itself
718
*/
719
((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) ||
720
/*
721
* Fallback solution if NaN compares to NaN
722
*/
723
((number != 0.0) &&
724
(fraction = modf(number, &integral),
725
integral == fraction)));
726
727
# if defined(TRIO_PLATFORM_UNIX)
728
internal_restore_signal_handler(SIGFPR, sigfpe_handler);
729
# endif
730
731
return status;
732
733
# endif
734
}
735
736
#endif /* TRIO_FUNC_INTERNAL_ISNAN */
737
738
#if defined(TRIO_FUNC_INTERNAL_ISINF)
739
740
TRIO_PRIVATE_NAN TRIO_INLINE int
741
internal_isinf
742
TRIO_ARGS1((number),
743
double number)
744
{
745
# if defined(TRIO_PLATFORM_SYMBIAN)
746
747
return isinf(number);
748
749
# endif
750
751
# if defined(TRIO_INTERNAL_ISINF_IEEE_754)
752
/*
753
* Examine IEEE 754 bit-pattern. Infinity must have a special exponent
754
* pattern, and an empty mantissa.
755
*/
756
int has_mantissa;
757
int is_special_quantity;
758
759
is_special_quantity = internal_is_special_quantity(number, &has_mantissa);
760
761
return (is_special_quantity && !has_mantissa)
762
? ((number < 0.0) ? -1 : 1)
763
: 0;
764
765
# endif
766
767
# if defined(TRIO_INTERNAL_ISINF_FALLBACK)
768
769
/*
770
* Fallback solution.
771
*/
772
int status;
773
774
# if defined(TRIO_PLATFORM_UNIX)
775
signal_handler_t sigfpe_handler = internal_ignore_signal_handler(SIGFPE);
776
# endif
777
778
double infinity = trio_pinf();
779
780
status = ((number == infinity)
781
? 1
782
: ((number == -infinity) ? -1 : 0));
783
784
# if defined(TRIO_PLATFORM_UNIX)
785
internal_restore_signal_handler(SIGFPE, sigfpe_handler);
786
# endif
787
788
return status;
789
790
# endif
791
}
792
793
#endif /* TRIO_FUNC_INTERNAL_ISINF */
794
795
/*************************************************************************
796
* Public functions
797
*/
798
799
#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
800
801
TRIO_PUBLIC_NAN int
802
trio_fpclassify_and_signbit
803
TRIO_ARGS2((number, is_negative),
804
double number,
805
int *is_negative)
806
{
807
/* The TRIO_FUNC_xxx_FPCLASSIFY_AND_SIGNBIT macros are mutually exclusive */
808
809
#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)
810
811
return c99_fpclassify_and_signbit(number, is_negative);
812
813
#endif
814
815
#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)
816
817
return decc_fpclassify_and_signbit(number, is_negative);
818
819
#endif
820
821
#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)
822
823
return ms_fpclassify_and_signbit(number, is_negative);
824
825
#endif
826
827
#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)
828
829
return hp_fpclassify_and_signbit(number, is_negative);
830
831
#endif
832
833
#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)
834
835
return xlc_fpclassify_and_signbit(number, is_negative);
836
837
#endif
838
839
#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)
840
841
/*
842
* Fallback solution.
843
*/
844
int rc;
845
846
if (number == 0.0) {
847
/*
848
* In IEEE 754 the sign of zero is ignored in comparisons, so we
849
* have to handle this as a special case by examining the sign bit
850
* directly.
851
*/
852
# if defined(TRIO_IEEE_754)
853
*is_negative = internal_is_negative(number);
854
# else
855
*is_negative = TRIO_FALSE; /* FIXME */
856
# endif
857
return TRIO_FP_ZERO;
858
}
859
if (internal_isnan(number)) {
860
*is_negative = TRIO_FALSE;
861
return TRIO_FP_NAN;
862
}
863
rc = internal_isinf(number);
864
if (rc != 0) {
865
*is_negative = (rc == -1);
866
return TRIO_FP_INFINITE;
867
}
868
if ((number > 0.0) && (number < DBL_MIN)) {
869
*is_negative = TRIO_FALSE;
870
return TRIO_FP_SUBNORMAL;
871
}
872
if ((number < 0.0) && (number > -DBL_MIN)) {
873
*is_negative = TRIO_TRUE;
874
return TRIO_FP_SUBNORMAL;
875
}
876
*is_negative = (number < 0.0);
877
return TRIO_FP_NORMAL;
878
879
#endif
880
}
881
882
#endif
883
884
/**
885
Check for NaN.
886
887
@param number An arbitrary floating-point number.
888
@return Boolean value indicating whether or not the number is a NaN.
889
*/
890
#if defined(TRIO_FUNC_ISNAN)
891
892
TRIO_PUBLIC_NAN int
893
trio_isnan
894
TRIO_ARGS1((number),
895
double number)
896
{
897
int dummy;
898
899
return (trio_fpclassify_and_signbit(number, &dummy) == TRIO_FP_NAN);
900
}
901
902
#endif
903
904
/**
905
Check for infinity.
906
907
@param number An arbitrary floating-point number.
908
@return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
909
*/
910
#if defined(TRIO_FUNC_ISINF)
911
912
TRIO_PUBLIC_NAN int
913
trio_isinf
914
TRIO_ARGS1((number),
915
double number)
916
{
917
int is_negative;
918
919
if (trio_fpclassify_and_signbit(number, &is_negative) == TRIO_FP_INFINITE)
920
{
921
return (is_negative) ? -1 : 1;
922
}
923
else
924
{
925
return 0;
926
}
927
}
928
929
#endif
930
931
/**
932
Check for finity.
933
934
@param number An arbitrary floating-point number.
935
@return Boolean value indicating whether or not the number is a finite.
936
*/
937
#if defined(TRIO_FUNC_ISFINITE)
938
939
TRIO_PUBLIC_NAN int
940
trio_isfinite
941
TRIO_ARGS1((number),
942
double number)
943
{
944
int dummy;
945
946
switch (trio_fpclassify_and_signbit(number, &dummy))
947
{
948
case TRIO_FP_INFINITE:
949
case TRIO_FP_NAN:
950
return 0;
951
default:
952
return 1;
953
}
954
}
955
956
#endif
957
958
/**
959
Examine the sign of a number.
960
961
@param number An arbitrary floating-point number.
962
@return Boolean value indicating whether or not the number has the
963
sign bit set (i.e. is negative).
964
*/
965
#if defined(TRIO_FUNC_SIGNBIT)
966
967
TRIO_PUBLIC_NAN int
968
trio_signbit
969
TRIO_ARGS1((number),
970
double number)
971
{
972
int is_negative;
973
974
(void)trio_fpclassify_and_signbit(number, &is_negative);
975
return is_negative;
976
}
977
978
#endif
979
980
/**
981
Examine the class of a number.
982
983
@param number An arbitrary floating-point number.
984
@return Enumerable value indicating the class of @p number
985
*/
986
#if defined(TRIO_FUNC_FPCLASSIFY)
987
988
TRIO_PUBLIC_NAN int
989
trio_fpclassify
990
TRIO_ARGS1((number),
991
double number)
992
{
993
int dummy;
994
995
return trio_fpclassify_and_signbit(number, &dummy);
996
}
997
998
#endif
999
1000
/**
1001
Generate negative zero.
1002
1003
@return Floating-point representation of negative zero.
1004
*/
1005
#if defined(TRIO_FUNC_NZERO)
1006
1007
TRIO_PUBLIC_NAN double
1008
trio_nzero(TRIO_NOARGS)
1009
{
1010
# if defined(TRIO_NZERO_IEEE_754)
1011
1012
return internal_make_double(ieee_754_negzero_array);
1013
1014
# endif
1015
1016
# if defined(TRIO_NZERO_FALLBACK)
1017
1018
TRIO_VOLATILE double zero = 0.0;
1019
1020
return -zero;
1021
1022
# endif
1023
}
1024
1025
#endif
1026
1027
/**
1028
Generate positive infinity.
1029
1030
@return Floating-point representation of positive infinity.
1031
*/
1032
#if defined(TRIO_FUNC_PINF)
1033
1034
TRIO_PUBLIC_NAN double
1035
trio_pinf(TRIO_NOARGS)
1036
{
1037
/* Cache the result */
1038
static double pinf_value = 0.0;
1039
1040
if (pinf_value == 0.0) {
1041
1042
# if defined(TRIO_PINF_C99_MACRO)
1043
1044
pinf_value = (double)INFINITY;
1045
1046
# endif
1047
1048
# if defined(TRIO_PINF_IEEE_754)
1049
1050
pinf_value = internal_make_double(ieee_754_infinity_array);
1051
1052
# endif
1053
1054
# if defined(TRIO_PINF_FALLBACK)
1055
/*
1056
* If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used
1057
* as infinity. Otherwise we have to resort to an overflow
1058
* operation to generate infinity.
1059
*/
1060
# if defined(TRIO_PLATFORM_UNIX)
1061
signal_handler_t sigfpe_handler = internal_ignore_signal_handler(SIGFPE);
1062
# endif
1063
1064
pinf_value = HUGE_VAL;
1065
if (HUGE_VAL == DBL_MAX) {
1066
/* Force overflow */
1067
pinf_value += HUGE_VAL;
1068
}
1069
1070
# if defined(TRIO_PLATFORM_UNIX)
1071
internal_restore_signal_handler(SIGFPE, sigfpe_handler);
1072
# endif
1073
1074
# endif
1075
}
1076
return pinf_value;
1077
}
1078
1079
#endif
1080
1081
/**
1082
Generate negative infinity.
1083
1084
@return Floating-point value of negative infinity.
1085
*/
1086
#if defined(TRIO_FUNC_NINF)
1087
1088
TRIO_PUBLIC_NAN double
1089
trio_ninf(TRIO_NOARGS)
1090
{
1091
static double ninf_value = 0.0;
1092
1093
if (ninf_value == 0.0) {
1094
/*
1095
* Negative infinity is calculated by negating positive infinity,
1096
* which can be done because it is legal to do calculations on
1097
* infinity (for example, 1 / infinity == 0).
1098
*/
1099
ninf_value = -trio_pinf();
1100
}
1101
return ninf_value;
1102
}
1103
1104
#endif
1105
1106
/**
1107
Generate NaN.
1108
1109
@return Floating-point representation of NaN.
1110
*/
1111
#if defined(TRIO_FUNC_NAN)
1112
1113
TRIO_PUBLIC_NAN double
1114
trio_nan(TRIO_NOARGS)
1115
{
1116
/* Cache the result */
1117
static double nan_value = 0.0;
1118
1119
if (nan_value == 0.0) {
1120
1121
# if defined(TRIO_NAN_C99_FUNCTION) || defined(TRIO_PLATFORM_SYMBIAN)
1122
1123
nan_value = nan("");
1124
1125
# endif
1126
1127
# if defined(TRIO_NAN_C99_MACRO)
1128
1129
nan_value = (double)NAN;
1130
1131
# endif
1132
1133
# if defined(TRIO_NAN_IEEE_754)
1134
1135
nan_value = internal_make_double(ieee_754_qnan_array);
1136
1137
# endif
1138
1139
# if defined(TRIO_NAN_FALLBACK)
1140
/*
1141
* There are several ways to generate NaN. The one used here is
1142
* to divide infinity by infinity. I would have preferred to add
1143
* negative infinity to positive infinity, but that yields wrong
1144
* result (infinity) on FreeBSD.
1145
*
1146
* This may fail if the hardware does not support NaN, or if
1147
* the Invalid Operation floating-point exception is unmasked.
1148
*/
1149
# if defined(TRIO_PLATFORM_UNIX)
1150
signal_handle_t sigfpe_handler = internal_ignore_signal_handler(SIGFPE);
1151
# endif
1152
1153
nan_value = trio_pinf() / trio_pinf();
1154
1155
# if defined(TRIO_PLATFORM_UNIX)
1156
internal_restore_signal_handler(SIGFPE, sigfpe_handler);
1157
# endif
1158
1159
# endif
1160
}
1161
return nan_value;
1162
}
1163
1164
#endif
1165
1166
/** @} SpecialQuantities */
1167
1168
/*************************************************************************
1169
* For test purposes.
1170
*
1171
* Add the following compiler option to include this test code.
1172
*
1173
* Unix : -DSTANDALONE
1174
* VMS : /DEFINE=(STANDALONE)
1175
*/
1176
#if defined(STANDALONE)
1177
# include <stdio.h>
1178
1179
static TRIO_CONST char *
1180
getClassification
1181
TRIO_ARGS1((type),
1182
int type)
1183
{
1184
switch (type) {
1185
case TRIO_FP_INFINITE:
1186
return "FP_INFINITE";
1187
case TRIO_FP_NAN:
1188
return "FP_NAN";
1189
case TRIO_FP_NORMAL:
1190
return "FP_NORMAL";
1191
case TRIO_FP_SUBNORMAL:
1192
return "FP_SUBNORMAL";
1193
case TRIO_FP_ZERO:
1194
return "FP_ZERO";
1195
default:
1196
return "FP_UNKNOWN";
1197
}
1198
}
1199
1200
static void
1201
print_class
1202
TRIO_ARGS2((prefix, number),
1203
TRIO_CONST char *prefix,
1204
double number)
1205
{
1206
printf("%-6s: %s %-15s %g\n",
1207
prefix,
1208
trio_signbit(number) ? "-" : "+",
1209
getClassification(trio_fpclassify(number)),
1210
number);
1211
}
1212
1213
int main(TRIO_NOARGS)
1214
{
1215
double my_nan;
1216
double my_pinf;
1217
double my_ninf;
1218
# if defined(TRIO_PLATFORM_UNIX)
1219
signal_handler_t signal_handler;
1220
# endif
1221
1222
my_nan = trio_nan();
1223
my_pinf = trio_pinf();
1224
my_ninf = trio_ninf();
1225
1226
print_class("Nan", my_nan);
1227
print_class("PInf", my_pinf);
1228
print_class("NInf", my_ninf);
1229
print_class("PZero", 0.0);
1230
print_class("NZero", -0.0);
1231
print_class("PNorm", 1.0);
1232
print_class("NNorm", -1.0);
1233
print_class("PSub", 1.01e-307 - 1.00e-307);
1234
print_class("NSub", 1.00e-307 - 1.01e-307);
1235
1236
printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1237
my_nan,
1238
((unsigned char *)&my_nan)[0],
1239
((unsigned char *)&my_nan)[1],
1240
((unsigned char *)&my_nan)[2],
1241
((unsigned char *)&my_nan)[3],
1242
((unsigned char *)&my_nan)[4],
1243
((unsigned char *)&my_nan)[5],
1244
((unsigned char *)&my_nan)[6],
1245
((unsigned char *)&my_nan)[7],
1246
trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));
1247
printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1248
my_pinf,
1249
((unsigned char *)&my_pinf)[0],
1250
((unsigned char *)&my_pinf)[1],
1251
((unsigned char *)&my_pinf)[2],
1252
((unsigned char *)&my_pinf)[3],
1253
((unsigned char *)&my_pinf)[4],
1254
((unsigned char *)&my_pinf)[5],
1255
((unsigned char *)&my_pinf)[6],
1256
((unsigned char *)&my_pinf)[7],
1257
trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));
1258
printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1259
my_ninf,
1260
((unsigned char *)&my_ninf)[0],
1261
((unsigned char *)&my_ninf)[1],
1262
((unsigned char *)&my_ninf)[2],
1263
((unsigned char *)&my_ninf)[3],
1264
((unsigned char *)&my_ninf)[4],
1265
((unsigned char *)&my_ninf)[5],
1266
((unsigned char *)&my_ninf)[6],
1267
((unsigned char *)&my_ninf)[7],
1268
trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));
1269
1270
# if defined(TRIO_PLATFORM_UNIX)
1271
signal_handler = internal_ignore_signal_handler(SIGFPE);
1272
# endif
1273
1274
my_pinf = DBL_MAX + DBL_MAX;
1275
my_ninf = -my_pinf;
1276
my_nan = my_pinf / my_pinf;
1277
1278
# if defined(TRIO_PLATFORM_UNIX)
1279
internal_restore_signal_handler(SIGFPE, signal_handler);
1280
# endif
1281
1282
printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1283
my_nan,
1284
((unsigned char *)&my_nan)[0],
1285
((unsigned char *)&my_nan)[1],
1286
((unsigned char *)&my_nan)[2],
1287
((unsigned char *)&my_nan)[3],
1288
((unsigned char *)&my_nan)[4],
1289
((unsigned char *)&my_nan)[5],
1290
((unsigned char *)&my_nan)[6],
1291
((unsigned char *)&my_nan)[7],
1292
trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));
1293
printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1294
my_pinf,
1295
((unsigned char *)&my_pinf)[0],
1296
((unsigned char *)&my_pinf)[1],
1297
((unsigned char *)&my_pinf)[2],
1298
((unsigned char *)&my_pinf)[3],
1299
((unsigned char *)&my_pinf)[4],
1300
((unsigned char *)&my_pinf)[5],
1301
((unsigned char *)&my_pinf)[6],
1302
((unsigned char *)&my_pinf)[7],
1303
trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));
1304
printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
1305
my_ninf,
1306
((unsigned char *)&my_ninf)[0],
1307
((unsigned char *)&my_ninf)[1],
1308
((unsigned char *)&my_ninf)[2],
1309
((unsigned char *)&my_ninf)[3],
1310
((unsigned char *)&my_ninf)[4],
1311
((unsigned char *)&my_ninf)[5],
1312
((unsigned char *)&my_ninf)[6],
1313
((unsigned char *)&my_ninf)[7],
1314
trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));
1315
1316
return 0;
1317
}
1318
#endif
1319
1320