nan64.c (1260B)
1 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */ 2 3 /* 4 * 64-bit IEEE not-a-number routines. 5 * This is big/little-endian portable assuming that 6 * the 64-bit doubles and 64-bit integers have the 7 * same byte ordering. 8 */ 9 10 #include "plan9.h" 11 #include <assert.h> 12 #include "fmt.h" 13 #include "fmtdef.h" 14 15 static uvlong uvnan = ((uvlong)0x7FF00000<<32)|0x00000001; 16 static uvlong uvinf = ((uvlong)0x7FF00000<<32)|0x00000000; 17 static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000; 18 19 /* gcc sees through the obvious casts. */ 20 static uvlong 21 d2u(double d) 22 { 23 union { 24 uvlong v; 25 double d; 26 } u; 27 assert(sizeof(u.d) == sizeof(u.v)); 28 u.d = d; 29 return u.v; 30 } 31 32 static double 33 u2d(uvlong v) 34 { 35 union { 36 uvlong v; 37 double d; 38 } u; 39 assert(sizeof(u.d) == sizeof(u.v)); 40 u.v = v; 41 return u.d; 42 } 43 44 double 45 __NaN(void) 46 { 47 return u2d(uvnan); 48 } 49 50 int 51 __isNaN(double d) 52 { 53 uvlong x; 54 55 x = d2u(d); 56 /* IEEE 754: exponent bits 0x7FF and non-zero mantissa */ 57 return (x&uvinf) == uvinf && (x&~uvneginf) != 0; 58 } 59 60 double 61 __Inf(int sign) 62 { 63 return u2d(sign < 0 ? uvneginf : uvinf); 64 } 65 66 int 67 __isInf(double d, int sign) 68 { 69 uvlong x; 70 71 x = d2u(d); 72 if(sign == 0) 73 return x==uvinf || x==uvneginf; 74 else if(sign > 0) 75 return x==uvinf; 76 else 77 return x==uvneginf; 78 }