nan64.c (1196B)
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 "plan9.h" 9 #include <assert.h> 10 #include "fmt.h" 11 #include "fmtdef.h" 12 13 static uvlong uvnan = ((uvlong)0x7FF00000<<32)|0x00000001; 14 static uvlong uvinf = ((uvlong)0x7FF00000<<32)|0x00000000; 15 static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000; 16 17 /* gcc sees through the obvious casts. */ 18 static uvlong 19 d2u(double d) 20 { 21 union { 22 uvlong v; 23 double d; 24 } u; 25 assert(sizeof(u.d) == sizeof(u.v)); 26 u.d = d; 27 return u.v; 28 } 29 30 static double 31 u2d(uvlong v) 32 { 33 union { 34 uvlong v; 35 double d; 36 } u; 37 assert(sizeof(u.d) == sizeof(u.v)); 38 u.v = v; 39 return u.d; 40 } 41 42 double 43 __NaN(void) 44 { 45 return u2d(uvnan); 46 } 47 48 int 49 __isNaN(double d) 50 { 51 uvlong x; 52 53 x = d2u(d); 54 /* IEEE 754: exponent bits 0x7FF and non-zero mantissa */ 55 return (x&uvinf) == uvinf && (x&~uvneginf) != 0; 56 } 57 58 double 59 __Inf(int sign) 60 { 61 return u2d(sign < 0 ? uvneginf : uvinf); 62 } 63 64 int 65 __isInf(double d, int sign) 66 { 67 uvlong x; 68 69 x = d2u(d); 70 if(sign == 0) 71 return x==uvinf || x==uvneginf; 72 else if(sign > 0) 73 return x==uvinf; 74 else 75 return x==uvneginf; 76 }