Skip to content

Commit ca23df4

Browse files
rhettingermiss-islington
authored andcommitted
gh-139074: Fix missing high precision case in sumprod() (gh-139075)
(cherry picked from commit b485e50) Co-authored-by: Raymond Hettinger <[email protected]>
1 parent fa6dbb1 commit ca23df4

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

Lib/test/test_math.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1366,7 +1366,9 @@ def __rmul__(self, other):
13661366

13671367
# Error cases that arose during development
13681368
args = ((-5, -5, 10), (1.5, 4611686018427387904, 2305843009213693952))
1369-
self.assertEqual(sumprod(*args), 0.0)
1369+
self.assertEqual(sumprod(*args), -7.5)
1370+
self.assertEqual(sumprod([-0.01, 1, -1, 0.01], [1, 1, 1, 1]), 0.0)
1371+
self.assertEqual(sumprod([1, 1, 1, 1], [-0.01, 1, -1, 0.01], ), 0.0)
13701372

13711373

13721374
@requires_IEEE_754
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a missing case in :func:`math.sumprod` where a low precision path was
2+
taken when an int/int input pair followed a float input.

Modules/mathmodule.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2885,32 +2885,31 @@ math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q)
28852885

28862886
if (!finished) {
28872887
double flt_p, flt_q;
2888-
bool p_type_float = PyFloat_CheckExact(p_i);
2889-
bool q_type_float = PyFloat_CheckExact(q_i);
2890-
if (p_type_float && q_type_float) {
2891-
flt_p = PyFloat_AS_DOUBLE(p_i);
2892-
flt_q = PyFloat_AS_DOUBLE(q_i);
2893-
} else if (p_type_float && (PyLong_CheckExact(q_i) || PyBool_Check(q_i))) {
2894-
/* We care about float/int pairs and int/float pairs because
2895-
they arise naturally in several use cases such as price
2896-
times quantity, measurements with integer weights, or
2897-
data selected by a vector of bools. */
2888+
2889+
if (PyFloat_CheckExact(p_i)) {
28982890
flt_p = PyFloat_AS_DOUBLE(p_i);
2899-
flt_q = PyLong_AsDouble(q_i);
2900-
if (flt_q == -1.0 && PyErr_Occurred()) {
2891+
} else if (PyLong_CheckExact(p_i) || PyBool_Check(p_i)) {
2892+
flt_p = PyLong_AsDouble(p_i);
2893+
if (flt_p == -1.0 && PyErr_Occurred()) {
29012894
PyErr_Clear();
29022895
goto finalize_flt_path;
29032896
}
2904-
} else if (q_type_float && (PyLong_CheckExact(p_i) || PyBool_Check(p_i))) {
2897+
} else {
2898+
goto finalize_flt_path;
2899+
}
2900+
2901+
if (PyFloat_CheckExact(q_i)) {
29052902
flt_q = PyFloat_AS_DOUBLE(q_i);
2906-
flt_p = PyLong_AsDouble(p_i);
2907-
if (flt_p == -1.0 && PyErr_Occurred()) {
2903+
} else if (PyLong_CheckExact(q_i) || PyBool_Check(q_i)) {
2904+
flt_q = PyLong_AsDouble(q_i);
2905+
if (flt_q == -1.0 && PyErr_Occurred()) {
29082906
PyErr_Clear();
29092907
goto finalize_flt_path;
29102908
}
29112909
} else {
29122910
goto finalize_flt_path;
29132911
}
2912+
29142913
TripleLength new_flt_total = tl_fma(flt_p, flt_q, flt_total);
29152914
if (isfinite(new_flt_total.hi)) {
29162915
flt_total = new_flt_total;

0 commit comments

Comments
 (0)