diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2009-04-18 11:48:33 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2009-04-18 11:48:33 (GMT) |
commit | e6a076d86c51c9d72fee088dd229a7662ccc6c19 (patch) | |
tree | 86dc10e5fbdf54b653ef87d7a6a8ae4425345ce9 /Lib/test | |
parent | 60fd0999cce17ec8603edf4219f686c37a260d7b (diff) | |
download | cpython-e6a076d86c51c9d72fee088dd229a7662ccc6c19.zip cpython-e6a076d86c51c9d72fee088dd229a7662ccc6c19.tar.gz cpython-e6a076d86c51c9d72fee088dd229a7662ccc6c19.tar.bz2 |
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.
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_float.py | 83 |
1 files changed, 83 insertions, 0 deletions
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 @@ class ReprTestCase(unittest.TestCase): 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 @@ def test_main(): IEEEFormatTestCase, FormatTestCase, ReprTestCase, + RoundTestCase, InfNanTest, HexFloatTestCase, ) |