xref: /plan9/sys/src/cmd/unix/drawterm/libc/nan64.c (revision 0d601874851962e88c6c60fdd2e637bba04e13c2)
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 <u.h>
9 #include <libc.h>
10 #include "fmtdef.h"
11 
12 #if defined (__APPLE__) || (__powerpc__)
13 #define _NEEDLL
14 #endif
15 
16 static uvlong uvnan    = ((uvlong)0x7FF00000<<32)|0x00000001;
17 static uvlong uvinf    = ((uvlong)0x7FF00000<<32)|0x00000000;
18 static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000;
19 
20 double
__NaN(void)21 __NaN(void)
22 {
23 	uvlong *p;
24 
25 	/* gcc complains about "return *(double*)&uvnan;" */
26 	p = &uvnan;
27 	return *(double*)p;
28 }
29 
30 int
__isNaN(double d)31 __isNaN(double d)
32 {
33 	uvlong x;
34 	double *p;
35 
36 	p = &d;
37 	x = *(uvlong*)p;
38 	return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
39 }
40 
41 double
__Inf(int sign)42 __Inf(int sign)
43 {
44 	uvlong *p;
45 
46 	if(sign < 0)
47 		p = &uvinf;
48 	else
49 		p = &uvneginf;
50 	return *(double*)p;
51 }
52 
53 int
__isInf(double d,int sign)54 __isInf(double d, int sign)
55 {
56 	uvlong x;
57 	double *p;
58 
59 	p = &d;
60 	x = *(uvlong*)p;
61 	if(sign == 0)
62 		return x==uvinf || x==uvneginf;
63 	else if(sign > 0)
64 		return x==uvinf;
65 	else
66 		return x==uvneginf;
67 }
68