]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-123836: workaround fmod(x, y) bug on Windows (GH-124171) (#124186)
authorSergey B Kirpichev <skirpichev@gmail.com>
Tue, 17 Sep 2024 19:44:52 +0000 (22:44 +0300)
committerGitHub <noreply@github.com>
Tue, 17 Sep 2024 19:44:52 +0000 (21:44 +0200)
Buildbot failure on Windows 10 with MSC v.1916 64 bit (AMD64):
FAIL: testFmod (test.test_math.MathTests.testFmod)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\buildarea\3.x.bolen-windows10\build\Lib\test\test_math.py", line 605, in testFmod
    self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0)
    ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\buildarea\3.x.bolen-windows10\build\Lib\test\test_math.py", line 258, in ftest
    self.fail("{}: {}".format(name, failure))
    ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: fmod(-10, 1): expected -0.0, got 0.0 (zero has wrong sign)

Here Windows loose sign of the result; if y is nonzero, the result
should have the same sign as x.

This amends commit 28aea5d07d.
(cherry picked from commit f4dd4402108cc005d45acd4ca83c8530c36a93ca)

Misc/NEWS.d/next/Library/2024-09-17-18-06-42.gh-issue-124171.PHCvRJ.rst [new file with mode: 0644]
Modules/mathmodule.c

diff --git a/Misc/NEWS.d/next/Library/2024-09-17-18-06-42.gh-issue-124171.PHCvRJ.rst b/Misc/NEWS.d/next/Library/2024-09-17-18-06-42.gh-issue-124171.PHCvRJ.rst
new file mode 100644 (file)
index 0000000..c2f0bb1
--- /dev/null
@@ -0,0 +1,3 @@
+Add workaround for broken :c:func:`!fmod()` implementations on Windows, that
+loose zero sign (e.g. ``fmod(-10, 1)`` returns ``0.0``).  Patch by Sergey B
+Kirpichev.
index 000803981edcf4df602de5cbea0fd42a8d717c4e..d856ff6c354a4047ad52598f6b86d55322964a85 100644 (file)
@@ -2343,6 +2343,15 @@ math_fmod_impl(PyObject *module, double x, double y)
         return PyFloat_FromDouble(x);
     errno = 0;
     r = fmod(x, y);
+#ifdef _MSC_VER
+    /* Windows (e.g. Windows 10 with MSC v.1916) loose sign
+       for zero result.  But C99+ says: "if y is nonzero, the result
+       has the same sign as x".
+     */
+    if (r == 0.0 && y != 0.0) {
+        r = copysign(r, x);
+    }
+#endif
     if (Py_IS_NAN(r)) {
         if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
             errno = EDOM;