From: Mark H Weaver Date: Tue, 16 Jul 2013 04:26:11 +0000 (-0400) Subject: Avoid lossy conversion from inum to double in numerical comparisons. X-Git-Url: http://git.hcoop.net/bpt/guile.git/commitdiff_plain/95ed221785f5b1203e998823455f682c1830498b Avoid lossy conversion from inum to double in numerical comparisons. * libguile/numbers.c (scm_less_p): Avoid converting inums to doubles. * test-suite/tests/numbers.test (<): Add tests. --- diff --git a/libguile/numbers.c b/libguile/numbers.c index 458a92f1c..d09b7c575 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -6767,7 +6767,25 @@ scm_less_p (SCM x, SCM y) return scm_from_bool (sgn > 0); } else if (SCM_REALP (y)) - return scm_from_bool ((double) xx < SCM_REAL_VALUE (y)); + { + /* We can safely take the ceiling of y without changing the + result of x= (double) (SCM_MOST_POSITIVE_FIXNUM+1)) + return SCM_BOOL_T; + else if (!(yy > (double) SCM_MOST_NEGATIVE_FIXNUM)) + /* The condition above is carefully written to include the + case where yy==NaN. */ + return SCM_BOOL_F; + else + /* yy is a finite integer that fits in an inum. */ + return scm_from_bool (xx < (scm_t_inum) yy); + } else if (SCM_FRACTIONP (y)) { /* "x < a/b" becomes "x*b < a" */ @@ -6810,7 +6828,25 @@ scm_less_p (SCM x, SCM y) else if (SCM_REALP (x)) { if (SCM_I_INUMP (y)) - return scm_from_bool (SCM_REAL_VALUE (x) < (double) SCM_I_INUM (y)); + { + /* We can safely take the floor of x without changing the + result of xinexact most-positive-fixnum))) + (pass-if (< (exact->inexact (- most-positive-fixnum)) (- most-positive-fixnum)))) + (with-test-prefix "flonum/frac" (pass-if (< 0.75 4/3)) (pass-if (< -0.75 4/3))