xref: /plan9/sys/src/cmd/unix/drawterm/libc/nan64.c (revision 0d601874851962e88c6c60fdd2e637bba04e13c2)
18ccd4a63SDavid du Colombier /*
28ccd4a63SDavid du Colombier  * 64-bit IEEE not-a-number routines.
38ccd4a63SDavid du Colombier  * This is big/little-endian portable assuming that
48ccd4a63SDavid du Colombier  * the 64-bit doubles and 64-bit integers have the
58ccd4a63SDavid du Colombier  * same byte ordering.
68ccd4a63SDavid du Colombier  */
78ccd4a63SDavid du Colombier 
88ccd4a63SDavid du Colombier #include <u.h>
98ccd4a63SDavid du Colombier #include <libc.h>
10*0d601874SDavid du Colombier #include "fmtdef.h"
118ccd4a63SDavid du Colombier 
12*0d601874SDavid du Colombier #if defined (__APPLE__) || (__powerpc__)
13*0d601874SDavid du Colombier #define _NEEDLL
14*0d601874SDavid du Colombier #endif
158ccd4a63SDavid du Colombier 
16*0d601874SDavid du Colombier static uvlong uvnan    = ((uvlong)0x7FF00000<<32)|0x00000001;
17*0d601874SDavid du Colombier static uvlong uvinf    = ((uvlong)0x7FF00000<<32)|0x00000000;
18*0d601874SDavid du Colombier static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000;
198ccd4a63SDavid du Colombier 
208ccd4a63SDavid du Colombier double
__NaN(void)218ccd4a63SDavid du Colombier __NaN(void)
228ccd4a63SDavid du Colombier {
23*0d601874SDavid du Colombier 	uvlong *p;
24*0d601874SDavid du Colombier 
25*0d601874SDavid du Colombier 	/* gcc complains about "return *(double*)&uvnan;" */
26*0d601874SDavid du Colombier 	p = &uvnan;
27*0d601874SDavid du Colombier 	return *(double*)p;
288ccd4a63SDavid du Colombier }
298ccd4a63SDavid du Colombier 
308ccd4a63SDavid du Colombier int
__isNaN(double d)318ccd4a63SDavid du Colombier __isNaN(double d)
328ccd4a63SDavid du Colombier {
33*0d601874SDavid du Colombier 	uvlong x;
34*0d601874SDavid du Colombier 	double *p;
35*0d601874SDavid du Colombier 
36*0d601874SDavid du Colombier 	p = &d;
37*0d601874SDavid du Colombier 	x = *(uvlong*)p;
388ccd4a63SDavid du Colombier 	return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
398ccd4a63SDavid du Colombier }
408ccd4a63SDavid du Colombier 
418ccd4a63SDavid du Colombier double
__Inf(int sign)428ccd4a63SDavid du Colombier __Inf(int sign)
438ccd4a63SDavid du Colombier {
44*0d601874SDavid du Colombier 	uvlong *p;
45*0d601874SDavid du Colombier 
468ccd4a63SDavid du Colombier 	if(sign < 0)
47*0d601874SDavid du Colombier 		p = &uvinf;
488ccd4a63SDavid du Colombier 	else
49*0d601874SDavid du Colombier 		p = &uvneginf;
50*0d601874SDavid du Colombier 	return *(double*)p;
518ccd4a63SDavid du Colombier }
528ccd4a63SDavid du Colombier 
538ccd4a63SDavid du Colombier int
__isInf(double d,int sign)548ccd4a63SDavid du Colombier __isInf(double d, int sign)
558ccd4a63SDavid du Colombier {
568ccd4a63SDavid du Colombier 	uvlong x;
57*0d601874SDavid du Colombier 	double *p;
588ccd4a63SDavid du Colombier 
59*0d601874SDavid du Colombier 	p = &d;
60*0d601874SDavid du Colombier 	x = *(uvlong*)p;
618ccd4a63SDavid du Colombier 	if(sign == 0)
628ccd4a63SDavid du Colombier 		return x==uvinf || x==uvneginf;
638ccd4a63SDavid du Colombier 	else if(sign > 0)
648ccd4a63SDavid du Colombier 		return x==uvinf;
658ccd4a63SDavid du Colombier 	else
668ccd4a63SDavid du Colombier 		return x==uvneginf;
678ccd4a63SDavid du Colombier }
68