Skip to content

Commit 55fbe24

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 0e4e608 commit 55fbe24

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
@@ -1385,7 +1385,9 @@ def __rmul__(self, other):
13851385

13861386
# Error cases that arose during development
13871387
args = ((-5, -5, 10), (1.5, 4611686018427387904, 2305843009213693952))
1388-
self.assertEqual(sumprod(*args), 0.0)
1388+
self.assertEqual(sumprod(*args), -7.5)
1389+
self.assertEqual(sumprod([-0.01, 1, -1, 0.01], [1, 1, 1, 1]), 0.0)
1390+
self.assertEqual(sumprod([1, 1, 1, 1], [-0.01, 1, -1, 0.01], ), 0.0)
13891391

13901392

13911393
@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
@@ -2886,32 +2886,31 @@ math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q)
28862886

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

0 commit comments

Comments
 (0)