Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Lib/test/test_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -2806,6 +2806,13 @@ def test_fma_zero_result(self):
self.assertIsPositiveZero(math.fma(-tiny, -tiny, -0.0))
self.assertIsNegativeZero(math.fma(-tiny, tiny, -0.0))

# gh-73468: On some platforms, libc fma() doesn't implement IEE 754-2008
# properly: it doesn't use the right sign when the result is zero.
@unittest.skipIf(
sys.platform.startswith(("freebsd", "netbsd", "emscripten"))
or (sys.platform == "android" and platform.machine() == "x86_64"),
f"this platform doesn't implement IEE 754-2008 properly")
def test_fma_zero_result2(self):
# Corner case where rounding the multiplication would
# give the wrong result.
x = float.fromhex('0x1p-500')
Expand Down
8 changes: 3 additions & 5 deletions Modules/mathmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2353,11 +2353,9 @@ math_fma_impl(PyObject *module, double x, double y, double z)
// Emscripten, musl C library), libc fma() doesn't implement
// IEEE 754-2008 properly: it doesn't use the right sign when the
// result is zero.
if (x && y) {
r = x * y;
}
else {
r = copysign(1, z) == 1 ? x*y + z : x*y;
r = x * y;
if ((!x || !y) && copysign(1, z) == 1) {
r += z;
}
}

Expand Down
Loading