diff options
| author | Sergey B Kirpichev <skirpichev@gmail.com> | 2024-07-29 03:56:40 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-29 03:56:40 (GMT) |
| commit | 169e7138ab84db465b6bf28e6c1dc6c39dbf89f4 (patch) | |
| tree | 21d936410ac4d1fee18f04f3223a688f71a3503c /Python/bltinmodule.c | |
| parent | bc93923a2dee00751e44da58b6967c63e3f5c392 (diff) | |
| download | cpython-169e7138ab84db465b6bf28e6c1dc6c39dbf89f4.zip cpython-169e7138ab84db465b6bf28e6c1dc6c39dbf89f4.tar.gz cpython-169e7138ab84db465b6bf28e6c1dc6c39dbf89f4.tar.bz2 | |
gh-122234: fix accuracy issues for sum() (#122236)
* Use compensated summation for complex sums with floating-point items.
This amends #121176.
* sum() specializations for floats and complexes now use
PyLong_AsDouble() instead of PyLong_AsLongAndOverflow() and
compensated summation as well.
Diffstat (limited to 'Python/bltinmodule.c')
| -rw-r--r-- | Python/bltinmodule.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 3f7bf4d..ae025e7 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2687,14 +2687,15 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) continue; } if (PyLong_Check(item)) { - long value; - int overflow; - value = PyLong_AsLongAndOverflow(item, &overflow); - if (!overflow) { - re_sum.hi += (double)value; + double value = PyLong_AsDouble(item); + if (value != -1.0 || !PyErr_Occurred()) { + re_sum = cs_add(re_sum, value); Py_DECREF(item); continue; } + else { + return NULL; + } } result = PyFloat_FromDouble(cs_to_double(re_sum)); if (result == NULL) { @@ -2736,19 +2737,20 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) continue; } if (PyLong_Check(item)) { - long value; - int overflow; - value = PyLong_AsLongAndOverflow(item, &overflow); - if (!overflow) { - re_sum.hi += (double)value; + double value = PyLong_AsDouble(item); + if (value != -1.0 || !PyErr_Occurred()) { + re_sum = cs_add(re_sum, value); im_sum.hi += 0.0; Py_DECREF(item); continue; } + else { + return NULL; + } } if (PyFloat_Check(item)) { double value = PyFloat_AS_DOUBLE(item); - re_sum.hi += value; + re_sum = cs_add(re_sum, value); im_sum.hi += 0.0; _Py_DECREF_SPECIALIZED(item, _PyFloat_ExactDealloc); continue; |
