|  | /* | 
|  | * The authors of this software are Rob Pike and Ken Thompson, | 
|  | * with contributions from Mike Burrows and Sean Dorward. | 
|  | * | 
|  | *     Copyright (c) 2002-2006 by Lucent Technologies. | 
|  | *     Portions Copyright (c) 2004 Google Inc. | 
|  | * | 
|  | * Permission to use, copy, modify, and distribute this software for any | 
|  | * purpose without fee is hereby granted, provided that this entire notice | 
|  | * is included in all copies of any software which is or includes a copy | 
|  | * or modification of this software and in all copies of the supporting | 
|  | * documentation for such software. | 
|  | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED | 
|  | * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES | 
|  | * NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING | 
|  | * THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. | 
|  | */ | 
|  |  | 
|  | /* | 
|  | * 64-bit IEEE not-a-number routines. | 
|  | * This is big/little-endian portable assuming that | 
|  | * the 64-bit doubles and 64-bit integers have the | 
|  | * same byte ordering. | 
|  | */ | 
|  |  | 
|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include "fmtdef.h" | 
|  |  | 
|  | static uvlong uvnan    = ((uvlong)0x7FF00000<<32)|0x00000001; | 
|  | static uvlong uvinf    = ((uvlong)0x7FF00000<<32)|0x00000000; | 
|  | static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000; | 
|  |  | 
|  | /* gcc sees through the obvious casts. */ | 
|  | static uvlong | 
|  | d2u(double d) | 
|  | { | 
|  | union { | 
|  | uvlong v; | 
|  | double d; | 
|  | } u; | 
|  | assert(sizeof(u.d) == sizeof(u.v)); | 
|  | u.d = d; | 
|  | return u.v; | 
|  | } | 
|  |  | 
|  | static double | 
|  | u2d(uvlong v) | 
|  | { | 
|  | union { | 
|  | uvlong v; | 
|  | double d; | 
|  | } u; | 
|  | assert(sizeof(u.d) == sizeof(u.v)); | 
|  | u.v = v; | 
|  | return u.d; | 
|  | } | 
|  |  | 
|  | double | 
|  | __NaN(void) | 
|  | { | 
|  | return u2d(uvnan); | 
|  | } | 
|  |  | 
|  | int | 
|  | __isNaN(double d) | 
|  | { | 
|  | uvlong x; | 
|  |  | 
|  | x = d2u(d); | 
|  | /* IEEE 754: exponent bits 0x7FF and non-zero mantissa */ | 
|  | return (x&uvinf) == uvinf && (x&~uvneginf) != 0; | 
|  | } | 
|  |  | 
|  | double | 
|  | __Inf(int sign) | 
|  | { | 
|  | return u2d(sign < 0 ? uvneginf : uvinf); | 
|  | } | 
|  |  | 
|  | int | 
|  | __isInf(double d, int sign) | 
|  | { | 
|  | uvlong x; | 
|  |  | 
|  | x = d2u(d); | 
|  | if(sign == 0) | 
|  | return x==uvinf || x==uvneginf; | 
|  | else if(sign > 0) | 
|  | return x==uvinf; | 
|  | else | 
|  | return x==uvneginf; | 
|  | } |