/* * 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; }