[pypy-commit] pypy default: 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:05 CEST 2015
Author: Armin Rigo <arigo at 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)
More information about the pypy-commit
mailing list