From d0be987e412b46d74cd39d574c5d60fe834c3a06 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 8 Sep 2024 06:10:09 +0300 Subject: [PATCH 1/2] gh-123811: test that round() can return signed zero --- Lib/test/test_float.py | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 36ba67ac7415e7..17f0d4ad0ac6ed 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -864,6 +864,28 @@ def test_short_repr(self): @support.requires_IEEE_754 class RoundTestCase(unittest.TestCase): + def assertFloatsAreIdentical(self, x, y): + """Fail unless floats x and y are identical, in the sense that: + (1) both x and y are nans, or + (2) both x and y are infinities, with the same sign, or + (3) both x and y are zeros, with the same sign, or + (4) x and y are both finite and nonzero, and x == y + """ + msg = 'floats {!r} and {!r} are not identical' + + if isnan(x) or isnan(y): + if isnan(x) and isnan(y): + return + elif x == y: + if x != 0.0: + return + # both zero; check that signs match + elif copysign(1.0, x) == copysign(1.0, y): + return + else: + msg += ': zeros have different signs' + self.fail(msg.format(x, y)) + def test_inf_nan(self): self.assertRaises(OverflowError, round, INF) self.assertRaises(OverflowError, round, -INF) @@ -892,10 +914,10 @@ def test_large_n(self): 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) + self.assertFloatsAreIdentical(round(123.456, n), 0.0) + self.assertFloatsAreIdentical(round(-123.456, n), -0.0) + self.assertFloatsAreIdentical(round(1e300, n), 0.0) + self.assertFloatsAreIdentical(round(1e-320, n), 0.0) def test_overflow(self): self.assertRaises(OverflowError, round, 1.6e308, -308) From 42c378316b4e757ab78395d5bd9bd8493eb5bf25 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 8 Sep 2024 16:23:15 +0300 Subject: [PATCH 2/2] redo on top of python/cpython#121071 --- Lib/test/test_float.py | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 9429cd26985c35..048bb14509064b 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -863,29 +863,7 @@ def test_short_repr(self): self.assertEqual(repr(float(negs)), str(float(negs))) @support.requires_IEEE_754 -class RoundTestCase(unittest.TestCase): - - def assertFloatsAreIdentical(self, x, y): - """Fail unless floats x and y are identical, in the sense that: - (1) both x and y are nans, or - (2) both x and y are infinities, with the same sign, or - (3) both x and y are zeros, with the same sign, or - (4) x and y are both finite and nonzero, and x == y - """ - msg = 'floats {!r} and {!r} are not identical' - - if isnan(x) or isnan(y): - if isnan(x) and isnan(y): - return - elif x == y: - if x != 0.0: - return - # both zero; check that signs match - elif copysign(1.0, x) == copysign(1.0, y): - return - else: - msg += ': zeros have different signs' - self.fail(msg.format(x, y)) +class RoundTestCase(unittest.TestCase, FloatsAreIdenticalMixin): def test_inf_nan(self): self.assertRaises(OverflowError, round, INF)