summaryrefslogtreecommitdiffstats
path: root/Python/bltinmodule.c
diff options
context:
space:
mode:
authorSergey B Kirpichev <skirpichev@gmail.com>2024-07-29 03:56:40 (GMT)
committerGitHub <noreply@github.com>2024-07-29 03:56:40 (GMT)
commit169e7138ab84db465b6bf28e6c1dc6c39dbf89f4 (patch)
tree21d936410ac4d1fee18f04f3223a688f71a3503c /Python/bltinmodule.c
parentbc93923a2dee00751e44da58b6967c63e3f5c392 (diff)
downloadcpython-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.c24
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;