https://github.com/python/cpython/commit/b485e50fde3be08d796a2dac66cb822da1226bb3
commit: b485e50fde3be08d796a2dac66cb822da1226bb3
branch: main
author: Raymond Hettinger <[email protected]>
committer: rhettinger <[email protected]>
date: 2025-09-17T16:50:15-05:00
summary:
gh-139074: Fix missing high precision case in sumprod() (gh-139075)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2025-09-17-13-21-26.gh-issue-139074.dVZO5F.rst
M Lib/test/test_math.py
M Modules/mathmodule.c
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index e3b0d4fa9eeeb3..92326a46c33963 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -1485,7 +1485,9 @@ def __rmul__(self, other):
# Error cases that arose during development
args = ((-5, -5, 10), (1.5, 4611686018427387904, 2305843009213693952))
- self.assertEqual(sumprod(*args), 0.0)
+ self.assertEqual(sumprod(*args), -7.5)
+ self.assertEqual(sumprod([-0.01, 1, -1, 0.01], [1, 1, 1, 1]), 0.0)
+ self.assertEqual(sumprod([1, 1, 1, 1], [-0.01, 1, -1, 0.01], ), 0.0)
@requires_IEEE_754
@unittest.skipIf(HAVE_DOUBLE_ROUNDING,
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2025-09-17-13-21-26.gh-issue-139074.dVZO5F.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-17-13-21-26.gh-issue-139074.dVZO5F.rst
new file mode 100644
index 00000000000000..56c9f21296d3ac
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-17-13-21-26.gh-issue-139074.dVZO5F.rst
@@ -0,0 +1,2 @@
+Fixed a missing case in :func:`math.sumprod` where a low precision path was
+taken when an int/int input pair followed a float input.
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index c631beb9ce5477..d8bf9e76cdd082 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -2937,32 +2937,31 @@ math_sumprod_impl(PyObject *module, PyObject *p,
PyObject *q)
if (!finished) {
double flt_p, flt_q;
- bool p_type_float = PyFloat_CheckExact(p_i);
- bool q_type_float = PyFloat_CheckExact(q_i);
- if (p_type_float && q_type_float) {
- flt_p = PyFloat_AS_DOUBLE(p_i);
- flt_q = PyFloat_AS_DOUBLE(q_i);
- } else if (p_type_float && (PyLong_CheckExact(q_i) ||
PyBool_Check(q_i))) {
- /* We care about float/int pairs and int/float pairs
because
- they arise naturally in several use cases such as price
- times quantity, measurements with integer weights, or
- data selected by a vector of bools. */
+
+ if (PyFloat_CheckExact(p_i)) {
flt_p = PyFloat_AS_DOUBLE(p_i);
- flt_q = PyLong_AsDouble(q_i);
- if (flt_q == -1.0 && PyErr_Occurred()) {
+ } else if (PyLong_CheckExact(p_i) || PyBool_Check(p_i)) {
+ flt_p = PyLong_AsDouble(p_i);
+ if (flt_p == -1.0 && PyErr_Occurred()) {
PyErr_Clear();
goto finalize_flt_path;
}
- } else if (q_type_float && (PyLong_CheckExact(p_i) ||
PyBool_Check(p_i))) {
+ } else {
+ goto finalize_flt_path;
+ }
+
+ if (PyFloat_CheckExact(q_i)) {
flt_q = PyFloat_AS_DOUBLE(q_i);
- flt_p = PyLong_AsDouble(p_i);
- if (flt_p == -1.0 && PyErr_Occurred()) {
+ } else if (PyLong_CheckExact(q_i) || PyBool_Check(q_i)) {
+ flt_q = PyLong_AsDouble(q_i);
+ if (flt_q == -1.0 && PyErr_Occurred()) {
PyErr_Clear();
goto finalize_flt_path;
}
} else {
goto finalize_flt_path;
}
+
TripleLength new_flt_total = tl_fma(flt_p, flt_q, flt_total);
if (isfinite(new_flt_total.hi)) {
flt_total = new_flt_total;
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]