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