xref: /plan9/sys/src/ape/lib/fmt/nan64.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
1 /*
2  * 64-bit IEEE not-a-number routines.
3  * This is big/little-endian portable assuming that
4  * the 64-bit doubles and 64-bit integers have the
5  * same byte ordering.
6  */
7 
8 #include "nan.h"
9 
10 typedef unsigned long long uvlong;
11 typedef unsigned long ulong;
12 
13 static uvlong uvnan    = 0x7FF0000000000001LL;
14 static uvlong uvinf    = 0x7FF0000000000000LL;
15 static uvlong uvneginf = 0xFFF0000000000000LL;
16 
17 double
__NaN(void)18 __NaN(void)
19 {
20 	uvlong *p;
21 
22 	/* gcc complains about "return *(double*)&uvnan;" */
23 	p = &uvnan;
24 	return *(double*)p;
25 }
26 
27 int
__isNaN(double d)28 __isNaN(double d)
29 {
30 	uvlong x;
31 	double *p;
32 
33 	p = &d;
34 	x = *(uvlong*)p;
35 	return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
36 }
37 
38 double
__Inf(int sign)39 __Inf(int sign)
40 {
41 	uvlong *p;
42 
43 	if(sign < 0)
44 		p = &uvinf;
45 	else
46 		p = &uvneginf;
47 	return *(double*)p;
48 }
49 
50 int
__isInf(double d,int sign)51 __isInf(double d, int sign)
52 {
53 	uvlong x;
54 	double *p;
55 
56 	p = &d;
57 	x = *(uvlong*)p;
58 	if(sign == 0)
59 		return x==uvinf || x==uvneginf;
60 	else if(sign > 0)
61 		return x==uvinf;
62 	else
63 		return x==uvneginf;
64 }
65 
66 
67