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