]> granicus.if.org Git - python/commitdiff
Issue #7070: Fix problem with builtin round function for large odd
authorMark Dickinson <dickinsm@gmail.com>
Mon, 9 Nov 2009 17:45:40 +0000 (17:45 +0000)
committerMark Dickinson <dickinsm@gmail.com>
Mon, 9 Nov 2009 17:45:40 +0000 (17:45 +0000)
integer arguments.  Also fixes the sign of round(-0.0).

Lib/test/test_builtin.py
Misc/NEWS
Python/bltinmodule.c

index d8e604158c7bcab9878bf8178bf2a6c8e8f919ff..04c2216765444170a06b4a570e2f3c0a212a0d41 100644 (file)
@@ -1,5 +1,6 @@
 # Python test set -- built-in functions
 
+import platform
 import test.test_support, unittest
 from test.test_support import fcmp, have_unicode, TESTFN, unlink, \
                               run_unittest, run_with_locale
@@ -1259,6 +1260,14 @@ class BuiltinTest(unittest.TestCase):
         self.assertRaises(TypeError, round, t)
         self.assertRaises(TypeError, round, t, 0)
 
+    def test_round_large(self):
+        # Issue #1869: integral floats should remain unchanged
+        self.assertEqual(round(5e15-1), 5e15-1)
+        self.assertEqual(round(5e15), 5e15)
+        self.assertEqual(round(5e15+1), 5e15+1)
+        self.assertEqual(round(5e15+2), 5e15+2)
+        self.assertEqual(round(5e15+3), 5e15+3)
+
     def test_setattr(self):
         setattr(sys, 'spam', 1)
         self.assertEqual(sys.spam, 1)
index 6d421872649e3947eaaaa2c7edaa5877e6b9db06..ae1be75729314ac96d75c30f9f934395d16bedbd 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 2.6.5
 Core and Builtins
 -----------------
 
+- Issue #7070: Fix round bug for large odd integer arguments.
+
 - Issue #7078: Set struct.__doc__ from _struct.__doc__.
 
 - Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which
index 015e16bbb8753108c41be00db92f92ed30c048f7..87da3c9fff12143bbb019b1490425709a9a06d96 100644 (file)
@@ -2120,7 +2120,7 @@ For most object types, eval(repr(object)) == object.");
 static PyObject *
 builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
 {
-       double number;
+       double number, abs_number, abs_result;
        double f;
        int ndigits = 0;
        int i;
@@ -2137,10 +2137,14 @@ builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
                number /= f;
        else
                number *= f;
-       if (number >= 0.0)
-               number = floor(number + 0.5);
-       else
-               number = ceil(number - 0.5);
+
+       /* round `number` to nearest integer, rounding halves away from zero */
+       abs_number = fabs(number);
+       abs_result = floor(abs_number);
+       if (abs_number - abs_result >= 0.5)
+               abs_result += 1.0;
+       number = copysign(abs_result, number);
+
        if (ndigits < 0)
                number *= f;
        else