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.
This commit is contained in:
Sergey B Kirpichev 2024-07-29 06:56:40 +03:00 committed by GitHub
parent bc93923a2d
commit 169e7138ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 22 additions and 11 deletions

View file

@ -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;