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