Andy Wingo <wi...@pobox.com> writes: > BTW: did you see the failures on darwin? > > http://hydra.nixos.org/build/882506/nixlog/1 > > Seems there were errors in: > > FAIL: numbers.test: max: infinities and NaNs: (real-nan? (max +nan.0 > -inf.0)) > FAIL: numbers.test: max: infinities and NaNs: (real-nan? (max -inf.0 > +nan.0)) > FAIL: numbers.test: min: infinities and NaNs: (eqv? -inf.0 (min -inf.0 > +nan.0)) > FAIL: numbers.test: min: infinities and NaNs: (eqv? -inf.0 (min +nan.0 > -inf.0))
Ah, I was using a non-portable extension of isinf(x) to determine the sign of the infinity. This patch should fix it. Thanks, Mark
>From 6801f4c8503be81c03f503520c8e2d70944f371d Mon Sep 17 00:00:00 2001 From: Mark H Weaver <m...@netris.org> Date: Wed, 2 Feb 2011 19:32:16 -0500 Subject: [PATCH] Fix non-portable usage of `isinf' in `max' and `min' * numbers.c: Add new macros DOUBLE_IS_POSITIVE_INFINITY and DOUBLE_IS_NEGATIVE_INFINITY. (scm_max, scm_min): Use the new macros to detect particular infinities. Previously we checked the return value of `isinf' to determine the sign of the infinity, but that is not portable. --- libguile/numbers.c | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libguile/numbers.c b/libguile/numbers.c index 18d5755..3be4478 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -83,6 +83,11 @@ typedef scm_t_signed_bits scm_t_inum; TODO: if it's available, use C99's isfinite(x) instead */ #define DOUBLE_IS_FINITE(x) (!isinf(x) && !isnan(x)) +/* On some platforms, isinf(x) returns 0, 1 or -1, indicating the sign + of the infinity, but other platforms return a boolean only. */ +#define DOUBLE_IS_POSITIVE_INFINITY(x) (isinf(x) && ((x) > 0)) +#define DOUBLE_IS_NEGATIVE_INFINITY(x) (isinf(x) && ((x) < 0)) + /* @@ -5251,9 +5256,9 @@ scm_max (SCM x, SCM y) /* If neither (xx > yy) nor (xx < yy), then either they're equal or one is a NaN */ else if (SCM_UNLIKELY (isnan (xx))) - return (isinf (yy) == 1) ? y : x; + return DOUBLE_IS_POSITIVE_INFINITY (yy) ? y : x; else if (SCM_UNLIKELY (isnan (yy))) - return (isinf (xx) == 1) ? x : y; + return DOUBLE_IS_POSITIVE_INFINITY (xx) ? x : y; /* xx == yy, but handle signed zeroes properly */ else if (double_is_non_negative_zero (yy)) return y; @@ -5411,9 +5416,9 @@ scm_min (SCM x, SCM y) /* If neither (xx < yy) nor (xx > yy), then either they're equal or one is a NaN */ else if (SCM_UNLIKELY (isnan (xx))) - return (isinf (yy) == -1) ? y : x; + return DOUBLE_IS_NEGATIVE_INFINITY (yy) ? y : x; else if (SCM_UNLIKELY (isnan (yy))) - return (isinf (xx) == -1) ? x : y; + return DOUBLE_IS_NEGATIVE_INFINITY (xx) ? x : y; /* xx == yy, but handle signed zeroes properly */ else if (double_is_non_negative_zero (xx)) return y; -- 1.5.6.5