xref: /plan9-contrib/sys/src/ape/lib/fmt/nan64.c (revision ec59a3ddbfceee0efe34584c2c9981a5e5ff1ec4)
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 #ifdef __APPLE__
11 #define _NEEDLL
12 #endif
13 
14 typedef unsigned long long uvlong;
15 typedef unsigned long ulong;
16 
17 #ifdef _NEEDLL
18 static uvlong uvnan    = 0x7FF0000000000001LL;
19 static uvlong uvinf    = 0x7FF0000000000000LL;
20 static uvlong uvneginf = 0xFFF0000000000000LL;
21 #else
22 static uvlong uvnan    = 0x7FF0000000000001;
23 static uvlong uvinf    = 0x7FF0000000000000;
24 static uvlong uvneginf = 0xFFF0000000000000;
25 #endif
26 
27 double
28 __NaN(void)
29 {
30 	uvlong *p;
31 
32 	/* gcc complains about "return *(double*)&uvnan;" */
33 	p = &uvnan;
34 	return *(double*)p;
35 }
36 
37 int
38 __isNaN(double d)
39 {
40 	uvlong x;
41 	double *p;
42 
43 	p = &d;
44 	x = *(uvlong*)p;
45 	return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
46 }
47 
48 double
49 __Inf(int sign)
50 {
51 	uvlong *p;
52 
53 	if(sign < 0)
54 		p = &uvinf;
55 	else
56 		p = &uvneginf;
57 	return *(double*)p;
58 }
59 
60 int
61 __isInf(double d, int sign)
62 {
63 	uvlong x;
64 	double *p;
65 
66 	p = &d;
67 	x = *(uvlong*)p;
68 	if(sign == 0)
69 		return x==uvinf || x==uvneginf;
70 	else if(sign > 0)
71 		return x==uvinf;
72 	else
73 		return x==uvneginf;
74 }
75 
76 
77