From bc1c9d7e6b3c01a54a66617d550a6af6b6d4167d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 28 Jan 1997 04:51:45 +0000 Subject: [PATCH] (isnan): Define even if LISP_FLOAT_TYPE is not defined, since fmod might need it. (fmod): Ensure that the magnitude of the result does not exceed that of the divisor, and that the sign of the result does not disagree with that of the dividend. This does not yield a particularly accurate result, but at least it will be in the range promised by fmod. --- src/data.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/data.c b/src/data.c index 6fac1131eba..96d0a1032e7 100644 --- a/src/data.c +++ b/src/data.c @@ -2007,11 +2007,11 @@ arith_driver (code, nargs, args) return val; } -#ifdef LISP_FLOAT_TYPE - #undef isnan #define isnan(x) ((x) != (x)) +#ifdef LISP_FLOAT_TYPE + Lisp_Object float_arith_driver (accum, argnum, code, nargs, args) double accum; @@ -2141,9 +2141,21 @@ double fmod (f1, f2) double f1, f2; { + double r = f1; + if (f2 < 0.0) f2 = -f2; - return (f1 - f2 * floor (f1/f2)); + + /* If the magnitude of the result exceeds that of the divisor, or + the sign of the result does not agree with that of the dividend, + iterate with the reduced value. This does not yield a + particularly accurate result, but at least it will be in the + range promised by fmod. */ + do + r -= f2 * floor (r / f2); + while (f2 <= (r < 0 ? -r : r) || ((r < 0) != (f1 < 0) && ! isnan (r))); + + return r; } #endif /* ! HAVE_FMOD */ -- 2.39.2