From octave-sources-request at bevo dot che dot wisc dot edu Sun Jul 23 21:43:34 2000 Subject: Patch for nan/inf support without HAVE_*... From: Edward Jason Riedy To: octave-sources at bevo dot che dot wisc dot edu Date: Sun, 23 Jul 2000 19:43:31 -0700 The appended patch should define xisnan, xfinite, and xisinf reasonably on all platforms Octave seems to support. An over-optimizing compiler will reduce the tests to the ones in the current code, so it should be no worse than at present. The only potential problem I can see is if overflow traps. Then the 2.0 * x tests may trap when x has the largest possible exponent on radix-2 floating point machines. I've generally enabled setting octave_Inf and octave_NaN through calculation. If ``[s]ome version of gcc on some old version of Linux used to crash'', well, people should upgrade. Also, many of the HAVE_ISNAN, etc. tests are superfluous even without my changes. Since xisnan is currently hard-wired to return false, you needn't worry about returning the undefined octave_NaN. This passes tests on my machine after manually undefining the right pieces of config.h. I have a PPro, so that's not surprising. One test does fail the suite (residue-1.m), but it returns the correct answer when run by hand. Likely a dejagnu version mismatch or something like that. Jason --- liboctave/lo-mappers.cc.orig Sun Jul 23 18:32:06 2000 +++ liboctave/lo-mappers.cc Sun Jul 23 18:43:36 2000 at @ -65,11 +65,7 @@ if (x < 0.0) return M_PI; else -#if defined (HAVE_ISNAN) return xisnan (x) ? octave_NaN : 0.0; -#else - return 0.0; -#endif } double at @ -87,11 +83,7 @@ double imag (double x) { -#if defined (HAVE_ISNAN) return xisnan (x) ? octave_NaN : 0.0; -#else - return 0.0; -#endif } double at @ -115,11 +107,7 @@ else if (x > 0.0) tmp = 1.0; -#if defined (HAVE_ISNAN) return xisnan (x) ? octave_NaN : tmp; -#else - return tmp; -#endif } double at @ -152,7 +140,12 @@ #if defined (HAVE_ISNAN) return isnan (x) != 0; #else - return false; + /* + Testing NaN == NaN returns false under arithmetics conforming to + IEEE 754. An over-zealous compiler may optimize x == x to true. + That is no worse than the ``return false'' which !(x==x) replaced. + */ + return !(x == x); #endif } at @ -164,7 +157,13 @@ #elif defined (HAVE_ISINF) && defined (HAVE_ISNAN) return (! isinf (x) && ! isnan (x)); #else - return true; + double tmp = 2.0 * x; + /* + Twice +/- infinity is still +/- infinity. Again, an over-zealous + compiler will reduce this to ``return true''. That was the previous + result returned. + */ + return (tmp != x); #endif } at @ -176,7 +175,9 @@ #elif defined (HAVE_FINITE) && defined (HAVE_ISNAN) return (! (finite (x) || isnan (x))); #else - return false; + // See comment in xfinite + double tmp = 2.0 * x; + return (tmp == x); #endif } at @ -291,11 +292,7 @@ bool xisnan (const Complex& x) { -#if defined (HAVE_ISNAN) - return (isnan (real (x)) || isnan (imag (x))); -#else - return false; -#endif + return (xisnan (real (x)) || xisnan (imag (x))); } bool --- liboctave/lo-ieee.cc.orig Sun Jul 23 18:39:38 2000 +++ liboctave/lo-ieee.cc Sun Jul 23 18:40:11 2000 at @ -56,8 +56,6 @@ void octave_ieee_init (void) { -#if defined (HAVE_ISINF) || defined (HAVE_FINITE) - // Some version of gcc on some old version of Linux used to crash when // trying to make Inf and NaN. at @ -79,17 +77,11 @@ } #endif -#endif - -#if defined (HAVE_ISNAN) - #if defined (__alpha__) && ! defined (linux) extern unsigned int DQNAN[2]; octave_NaN = (*(X_CAST(double *, DQNAN))); #else octave_NaN = octave_Inf / octave_Inf; -#endif - #endif } ----------------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.che.wisc.edu/octave/octave.html How to fund new projects: http://www.che.wisc.edu/octave/funding.html Subscription information: http://www.che.wisc.edu/octave/archive.html -----------------------------------------------------------------------