mirror of
https://github.com/python/cpython.git
synced 2025-08-22 09:45:06 +00:00
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:
parent
bc93923a2d
commit
169e7138ab
3 changed files with 22 additions and 11 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue