Author: Ronan Lamy <[email protected]>
Branch: py3.6
Changeset: r98279:8e5e71e1a26e
Date: 2019-12-12 16:05 +0000
http://bitbucket.org/pypy/pypy/changeset/8e5e71e1a26e/

Log:    Return W_IntObject from float.__round__() when possible.

        This should speed up all calculations involving int(round(<float>)),
        fixing e.g. issue #2634.

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
@@ -145,6 +145,14 @@
         return space.w_NotImplemented
     return func_with_new_name(_compare, 'descr_' + opname)
 
+def _newint_from_float(space, floatval):
+    try:
+        value = ovfcheck_float_to_int(floatval)
+    except OverflowError:
+        return newlong_from_float(space, floatval)
+    else:
+        return space.newint(value)
+
 
 class W_FloatObject(W_Root):
     """This is a implementation of the app-level 'float' type.
@@ -440,12 +448,7 @@
         return W_FloatObject(a)
 
     def descr_trunc(self, space):
-        try:
-            value = ovfcheck_float_to_int(self.floatval)
-        except OverflowError:
-            return newlong_from_float(space, self.floatval)
-        else:
-            return space.newint(value)
+        return _newint_from_float(space, self.floatval)
 
     def descr_neg(self, space):
         return W_FloatObject(-self.floatval)
@@ -935,7 +938,7 @@
         if math.fabs(x - rounded) == 0.5:
             # halfway case: round to even
             rounded = 2.0 * rfloat.round_away(x / 2.0)
-        return newlong_from_float(space, rounded)
+        return _newint_from_float(space, rounded)
 
     # interpret 2nd argument as a Py_ssize_t; clip on overflow
     ndigits = space.getindex_w(w_ndigits, None)
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
@@ -5,6 +5,7 @@
 import py
 
 from pypy.objspace.std.floatobject import W_FloatObject, _remove_underscores
+from pypy.objspace.std.intobject import W_IntObject
 
 
 class TestW_FloatObject:
@@ -127,6 +128,10 @@
         for s in invalid:
             pytest.raises(ValueError, _remove_underscores, s)
 
+def test_avoid_bigints(space):
+    w_f = space.newfloat(123.456)
+    assert isinstance(w_f.descr_trunc(space), W_IntObject)
+    assert isinstance(w_f.descr___round__(space), W_IntObject)
 
 
 class AppTestAppFloatTest:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to