| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -196,6 +196,26 @@ def assertEqualAndEqualSign(self, a, b): | |||
| 196 | 196 | # distingishes -0.0 and 0.0. | |
| 197 | 197 | self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b))) | |
| 198 | 198 | ||
| 199 | + @requires_IEEE_754 | ||
| 200 | + def test_float_mod(self): | ||
| 201 | + # Check behaviour of % operator for IEEE 754 special cases. | ||
| 202 | + # In particular, check signs of zeros. | ||
| 203 | + mod = operator.mod | ||
| 204 | + | ||
| 205 | + self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0) | ||
| 206 | + self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0) | ||
| 207 | + self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0) | ||
| 208 | + self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0) | ||
| 209 | + self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100) | ||
| 210 | + self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0) | ||
| 211 | + | ||
| 212 | + self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0) | ||
| 213 | + self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100) | ||
| 214 | + self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0) | ||
| 215 | + self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0) | ||
| 216 | + self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0) | ||
| 217 | + self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0) | ||
| 218 | + | ||
| 199 | 219 | @requires_IEEE_754 | |
| 200 | 220 | def test_float_pow(self): | |
| 201 | 221 | # test builtin pow and ** operator for IEEE 754 special cases. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,10 @@ What's New in Python 3.2 Beta 1? | |||
| 10 | 10 | Core and Builtins | |
| 11 | 11 | ----------------- | |
| 12 | 12 | ||
| 13 | + - Issue #10596: Fix float.__mod__ to have the same behaviour as | ||
| 14 | + float.__divmod__ with respect to signed zeros. -4.0 % 4.0 should be | ||
| 15 | + 0.0, not -0.0. | ||
| 16 | + | ||
| 13 | 17 | - Issue #1772833: Add the -q command-line option to suppress copyright | |
| 14 | 18 | and version output in interactive mode. | |
| 15 | 19 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -600,10 +600,20 @@ float_rem(PyObject *v, PyObject *w) | |||
| 600 | 600 | } | |
| 601 | 601 | PyFPE_START_PROTECT("modulo", return 0) | |
| 602 | 602 | mod = fmod(vx, wx); | |
| 603 | - /* note: checking mod*wx < 0 is incorrect -- underflows to | ||
| 604 | - 0 if wx < sqrt(smallest nonzero double) */ | ||
| 605 | - if (mod && ((wx < 0) != (mod < 0))) { | ||
| 606 | - mod += wx; | ||
| 603 | + if (mod) { | ||
| 604 | + /* ensure the remainder has the same sign as the denominator */ | ||
| 605 | + if ((wx < 0) != (mod < 0)) { | ||
| 606 | + mod += wx; | ||
| 607 | + } | ||
| 608 | + } | ||
| 609 | + else { | ||
| 610 | + /* the remainder is zero, and in the presence of signed zeroes | ||
| 611 | + fmod returns different results across platforms; ensure | ||
| 612 | + it has the same sign as the denominator; we'd like to do | ||
| 613 | + "mod = wx * 0.0", but that may get optimized away */ | ||
| 614 | + mod *= mod; /* hide "mod = +0" from optimizer */ | ||
| 615 | + if (wx < 0.0) | ||
| 616 | + mod = -mod; | ||
| 607 | 617 | } | |
| 608 | 618 | PyFPE_END_PROTECT(mod) | |
| 609 | 619 | return PyFloat_FromDouble(mod); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments