diff options
Diffstat (limited to 'lib/isnan.c')
-rw-r--r-- | lib/isnan.c | 46 |
1 files changed, 15 insertions, 31 deletions
diff --git a/lib/isnan.c b/lib/isnan.c index d70c9348..a59dea79 100644 --- a/lib/isnan.c +++ b/lib/isnan.c @@ -1,5 +1,5 @@ /* Test for NaN that does not need libm. - Copyright (C) 2007-2015 Free Software Foundation, Inc. + Copyright (C) 2007-2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -21,7 +21,7 @@ /* Specification. */ #ifdef USE_LONG_DOUBLE /* Specification found in math.h or isnanl-nolibm.h. */ -extern int rpl_isnanl (long double x) _GL_ATTRIBUTE_CONST; +extern int rpl_isnanl (long double x); #elif ! defined USE_FLOAT /* Specification found in math.h or isnand-nolibm.h. */ extern int rpl_isnand (double x); @@ -79,22 +79,11 @@ extern int rpl_isnanf (float x); ((sizeof (DOUBLE) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) typedef union { DOUBLE value; unsigned int word[NWORDS]; } memory_double; -/* Most hosts nowadays use IEEE floating point, so they use IEC 60559 - representations, have infinities and NaNs, and do not trap on - exceptions. Define IEEE_FLOATING_POINT if this host is one of the - typical ones. The C11 macro __STDC_IEC_559__ is close to what is - wanted here, but is not quite right because this file does not require - all the features of C11 Annex F (and does not require C11 at all, - for that matter). */ - -#define IEEE_FLOATING_POINT (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \ - && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128) - int FUNC (DOUBLE x) { -#if defined KNOWN_EXPBIT0_LOCATION && IEEE_FLOATING_POINT -# if defined USE_LONG_DOUBLE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE +#ifdef KNOWN_EXPBIT0_LOCATION +# if defined USE_LONG_DOUBLE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) /* Special CPU dependent code is needed to treat bit patterns outside the IEEE 754 specification (such as Pseudo-NaNs, Pseudo-Infinities, Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals) as NaNs. @@ -128,20 +117,16 @@ FUNC (DOUBLE x) # else /* Be careful to not do any floating-point operation on x, such as x == x, because x may be a signaling NaN. */ -# if defined __SUNPRO_C || defined __ICC || defined _MSC_VER \ - || defined __DECC || defined __TINYC__ \ - || (defined __sgi && !defined __GNUC__) - /* The Sun C 5.0, Intel ICC 10.0, Microsoft Visual C/C++ 9.0, Compaq (ex-DEC) - 6.4, and TinyCC compilers don't recognize the initializers as constant - expressions. The Compaq compiler also fails when constant-folding - 0.0 / 0.0 even when constant-folding is not required. The Microsoft - Visual C/C++ compiler also fails when constant-folding 1.0 / 0.0 even - when constant-folding is not required. The SGI MIPSpro C compiler - complains about "floating-point operation result is out of range". */ +# if defined __SUNPRO_C || defined __DECC || (defined __sgi && !defined __GNUC__) + /* The Sun C 5.0 compilers and the Compaq (ex-DEC) 6.4 compilers don't + recognize the initializers as constant expressions. The latter compiler + also fails when constant-folding 0.0 / 0.0 even when constant-folding is + not required. The SGI MIPSpro C compiler complains about "floating-point + operation result is out of range". */ static DOUBLE zero = L_(0.0); memory_double nan; - DOUBLE plus_inf = L_(1.0) / zero; - DOUBLE minus_inf = -L_(1.0) / zero; + DOUBLE plus_inf = L_(1.0) / L_(0.0); + DOUBLE minus_inf = -L_(1.0) / L_(0.0); nan.value = zero / zero; # else static memory_double nan = { L_(0.0) / L_(0.0) }; @@ -164,12 +149,11 @@ FUNC (DOUBLE x) } # endif #else - /* The configuration did not find sufficient information, or does - not use IEEE floating point. Give up about the signaling NaNs; - handle only the quiet NaNs. */ + /* The configuration did not find sufficient information. Give up about + the signaling NaNs, handle only the quiet NaNs. */ if (x == x) { -# if defined USE_LONG_DOUBLE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE +# if defined USE_LONG_DOUBLE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) /* Detect any special bit patterns that pass ==; see comment above. */ memory_double m1; memory_double m2; |