Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r79847:680327d8b1a3 Date: 2015-09-26 08:01 +0200 http://bitbucket.org/pypy/pypy/changeset/680327d8b1a3/
Log: Issue #2145: fix the logic for "float == large_int_but_not_a_long" on 64-bit machines. It happened to work on x86-64 for example, but not on ppc64le. diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -4,6 +4,7 @@ from rpython.rlib import rarithmetic, rfloat from rpython.rlib.rarithmetic import LONG_BIT, intmask, ovfcheck_float_to_int +from rpython.rlib.rarithmetic import int_between from rpython.rlib.rbigint import rbigint from rpython.rlib.rfloat import ( DTSF_ADD_DOT_0, DTSF_STR_PRECISION, INFINITY, NAN, copysign, @@ -121,10 +122,11 @@ if space.isinstance_w(w_other, space.w_int): f1 = self.floatval i2 = space.int_w(w_other) - f2 = float(i2) - if LONG_BIT > 32 and int(f2) != i2: + # (double-)floats have always at least 48 bits of precision + if LONG_BIT > 32 and not int_between((-1)<<48, i2, 1<<48): res = do_compare_bigint(f1, rbigint.fromint(i2)) else: + f2 = float(i2) res = op(f1, f2) return space.newbool(res) if space.isinstance_w(w_other, space.w_long): diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py --- a/pypy/objspace/std/test/test_floatobject.py +++ b/pypy/objspace/std/test/test_floatobject.py @@ -840,3 +840,12 @@ check(mod(0.0, -1.0), -0.0) check(mod(1e-100, -1.0), -1.0) check(mod(1.0, -1.0), -0.0) + + def test_equality_rounding(self): + i = int(2 ** 63 - 1) + f = float(i) # not enough precision, becomes 2.0 ** 63 + assert f == 2.0 ** 63 + assert i != f + assert f != i + assert long(i) != f + assert f != long(i) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit