X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fisnan.c;h=d95e4bac77c54c14604eefe6246db887f3f5fc1d;hb=ec68a6fee63ee22364cb88f215b906989ab6b33c;hp=81f394d1654ac7f1ea66a4413fdfd67a75a9c536;hpb=06945b7c073c0872ec2049c0e0b94f789bf8d77e;p=gnulib.git diff --git a/lib/isnan.c b/lib/isnan.c index 81f394d16..d95e4bac7 100644 --- a/lib/isnan.c +++ b/lib/isnan.c @@ -1,5 +1,5 @@ /* Test for NaN that does not need libm. - Copyright (C) 2007-2008 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,8 +18,19 @@ #include +/* Specification. */ +#ifdef USE_LONG_DOUBLE +/* Specification found in math.h or isnanl-nolibm.h. */ +extern int rpl_isnanl (long double x) _GL_ATTRIBUTE_CONST; +#elif ! defined USE_FLOAT +/* Specification found in math.h or isnand-nolibm.h. */ +extern int rpl_isnand (double x); +#else /* defined USE_FLOAT */ +/* Specification found in math.h or isnanf-nolibm.h. */ +extern int rpl_isnanf (float x); +#endif + #include -#include #include #include "float+.h" @@ -72,7 +83,7 @@ int FUNC (DOUBLE x) { #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_)) +# 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 /* 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. @@ -106,16 +117,21 @@ 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 __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". */ +# 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". */ + static DOUBLE zero = L_(0.0); memory_double nan; - DOUBLE plus_inf = L_(1.0) / L_(0.0); - DOUBLE minus_inf = -L_(1.0) / L_(0.0); - nan.value = NAN; + DOUBLE plus_inf = L_(1.0) / zero; + DOUBLE minus_inf = -L_(1.0) / zero; + nan.value = zero / zero; # else static memory_double nan = { L_(0.0) / L_(0.0) }; static DOUBLE plus_inf = L_(1.0) / L_(0.0); @@ -128,10 +144,10 @@ FUNC (DOUBLE x) -Infinity, which have the same exponent. */ m.value = x; if (((m.word[EXPBIT0_WORD] ^ nan.word[EXPBIT0_WORD]) - & (EXP_MASK << EXPBIT0_BIT)) - == 0) + & (EXP_MASK << EXPBIT0_BIT)) + == 0) return (memcmp (&m.value, &plus_inf, SIZE) != 0 - && memcmp (&m.value, &minus_inf, SIZE) != 0); + && memcmp (&m.value, &minus_inf, SIZE) != 0); else return 0; } @@ -141,7 +157,7 @@ FUNC (DOUBLE x) 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_)) +# 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 /* Detect any special bit patterns that pass ==; see comment above. */ memory_double m1; memory_double m2;