Issue #1869 (and 4707, 5118, 5473, 1456775): use the new
string <-> float conversion routines to make round(x, n) correctly
rounded for floats x, so that it always agrees with format(x, '.<n>f').
Also fix some other round nuisances, like round(123.456, 1-2**31) giving
an integer rather than a float.
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index 24202be..91ed054 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -389,6 +389,88 @@
self.assertEqual(s, repr(float(s)))
self.assertEqual(negs, repr(float(negs)))
+class RoundTestCase(unittest.TestCase):
+ @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
+ "test requires IEEE 754 doubles")
+ def test_inf_nan(self):
+ self.assertRaises(OverflowError, round, INF)
+ self.assertRaises(OverflowError, round, -INF)
+ self.assertRaises(ValueError, round, NAN)
+
+ @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
+ "test requires IEEE 754 doubles")
+ def test_large_n(self):
+ for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]:
+ self.assertEqual(round(123.456, n), 123.456)
+ self.assertEqual(round(-123.456, n), -123.456)
+ self.assertEqual(round(1e300, n), 1e300)
+ self.assertEqual(round(1e-320, n), 1e-320)
+ self.assertEqual(round(1e150, 300), 1e150)
+ self.assertEqual(round(1e300, 307), 1e300)
+ self.assertEqual(round(-3.1415, 308), -3.1415)
+ self.assertEqual(round(1e150, 309), 1e150)
+ self.assertEqual(round(1.4e-315, 315), 1e-315)
+
+ @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
+ "test requires IEEE 754 doubles")
+ def test_small_n(self):
+ for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]:
+ self.assertEqual(round(123.456, n), 0.0)
+ self.assertEqual(round(-123.456, n), -0.0)
+ self.assertEqual(round(1e300, n), 0.0)
+ self.assertEqual(round(1e-320, n), 0.0)
+
+ @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
+ "test requires IEEE 754 doubles")
+ def test_overflow(self):
+ self.assertRaises(OverflowError, round, 1.6e308, -308)
+ self.assertRaises(OverflowError, round, -1.7e308, -308)
+
+ @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
+ "applies only when using short float repr style")
+ def test_previous_round_bugs(self):
+ # particular cases that have occurred in bug reports
+ self.assertEqual(round(562949953421312.5, 1),
+ 562949953421312.5)
+ self.assertEqual(round(56294995342131.5, 3),
+ 56294995342131.5)
+ # round-half-even
+ self.assertEqual(round(25.0, -1), 20.0)
+ self.assertEqual(round(35.0, -1), 40.0)
+ self.assertEqual(round(45.0, -1), 40.0)
+ self.assertEqual(round(55.0, -1), 60.0)
+ self.assertEqual(round(65.0, -1), 60.0)
+ self.assertEqual(round(75.0, -1), 80.0)
+ self.assertEqual(round(85.0, -1), 80.0)
+ self.assertEqual(round(95.0, -1), 100.0)
+
+ @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
+ "applies only when using short float repr style")
+ def test_matches_float_format(self):
+ # round should give the same results as float formatting
+ for i in range(500):
+ x = i/1000.
+ self.assertEqual(float(format(x, '.0f')), round(x, 0))
+ self.assertEqual(float(format(x, '.1f')), round(x, 1))
+ self.assertEqual(float(format(x, '.2f')), round(x, 2))
+ self.assertEqual(float(format(x, '.3f')), round(x, 3))
+
+ for i in range(5, 5000, 10):
+ x = i/1000.
+ self.assertEqual(float(format(x, '.0f')), round(x, 0))
+ self.assertEqual(float(format(x, '.1f')), round(x, 1))
+ self.assertEqual(float(format(x, '.2f')), round(x, 2))
+ self.assertEqual(float(format(x, '.3f')), round(x, 3))
+
+ for i in range(500):
+ x = random.random()
+ self.assertEqual(float(format(x, '.0f')), round(x, 0))
+ self.assertEqual(float(format(x, '.1f')), round(x, 1))
+ self.assertEqual(float(format(x, '.2f')), round(x, 2))
+ self.assertEqual(float(format(x, '.3f')), round(x, 3))
+
+
+
# Beginning with Python 2.6 float has cross platform compatible
# ways to create and represent inf and nan
class InfNanTest(unittest.TestCase):
@@ -878,6 +960,7 @@
IEEEFormatTestCase,
FormatTestCase,
ReprTestCase,
+ RoundTestCase,
InfNanTest,
HexFloatTestCase,
)