github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/lib9/fmt/nan64.c (about) 1 /* 2 * The authors of this software are Rob Pike and Ken Thompson, 3 * with contributions from Mike Burrows and Sean Dorward. 4 * 5 * Copyright (c) 2002-2006 by Lucent Technologies. 6 * Portions Copyright (c) 2004 Google Inc. 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose without fee is hereby granted, provided that this entire notice 10 * is included in all copies of any software which is or includes a copy 11 * or modification of this software and in all copies of the supporting 12 * documentation for such software. 13 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 14 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES 15 * NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING 16 * THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 17 */ 18 19 /* 20 * 64-bit IEEE not-a-number routines. 21 * This is big/little-endian portable assuming that 22 * the 64-bit doubles and 64-bit integers have the 23 * same byte ordering. 24 */ 25 26 #include <u.h> 27 #include <libc.h> 28 #include "fmtdef.h" 29 30 static uvlong uvnan = ((uvlong)0x7FF00000<<32)|0x00000001; 31 static uvlong uvinf = ((uvlong)0x7FF00000<<32)|0x00000000; 32 static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000; 33 34 /* gcc sees through the obvious casts. */ 35 static uvlong 36 d2u(double d) 37 { 38 union { 39 uvlong v; 40 double d; 41 } u; 42 assert(sizeof(u.d) == sizeof(u.v)); 43 u.d = d; 44 return u.v; 45 } 46 47 static double 48 u2d(uvlong v) 49 { 50 union { 51 uvlong v; 52 double d; 53 } u; 54 assert(sizeof(u.d) == sizeof(u.v)); 55 u.v = v; 56 return u.d; 57 } 58 59 double 60 __NaN(void) 61 { 62 return u2d(uvnan); 63 } 64 65 int 66 __isNaN(double d) 67 { 68 uvlong x; 69 70 x = d2u(d); 71 /* IEEE 754: exponent bits 0x7FF and non-zero mantissa */ 72 return (x&uvinf) == uvinf && (x&~uvneginf) != 0; 73 } 74 75 double 76 __Inf(int sign) 77 { 78 return u2d(sign < 0 ? uvneginf : uvinf); 79 } 80 81 int 82 __isInf(double d, int sign) 83 { 84 uvlong x; 85 86 x = d2u(d); 87 if(sign == 0) 88 return x==uvinf || x==uvneginf; 89 else if(sign > 0) 90 return x==uvinf; 91 else 92 return x==uvneginf; 93 }