[pypy-commit] pypy ppc-updated-backend: Issue #2145: fix the logic for "float == large_int_but_not_a_long" on

arigo noreply at buildbot.pypy.org
Sat Sep 26 08:02:08 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: ppc-updated-backend
Changeset: r79848:539582e91229
Date: 2015-09-26 08:01 +0200
http://bitbucket.org/pypy/pypy/changeset/539582e91229/

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)


More information about the pypy-commit mailing list