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