Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Lib/test/test_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,9 @@ def test_sum_accuracy(self):
self.assertEqual(sum([1.0, 10E100, 1.0, -10E100, 2j]), 2+2j)
self.assertEqual(sum([2+1j, 10E100j, 1j, -10E100j]), 2+2j)
self.assertEqual(sum([1j, 1, 10E100j, 1j, 1.0, -10E100j]), 2+2j)
self.assertEqual(sum([2j, 1., 10E100, 1., -10E100]), 2+2j)
self.assertEqual(sum([1.0, 10**100, 1.0, -10**100]), 2.0)
self.assertEqual(sum([2j, 1.0, 10**100, 1.0, -10**100]), 2+2j)
self.assertEqual(sum([0.1j]*10 + [fractions.Fraction(1, 10)]), 0.1+1j)

def test_type(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Specializations for sums with float and complex inputs in :func:`sum()` now
always use compensated summation. Also, for integer items in above
specializations: :c:func:`PyLong_AsDouble` is used, instead of
:c:func:`PyLong_AsLongAndOverflow`. Patch by Sergey B Kirpichev.
18 changes: 7 additions & 11 deletions Python/bltinmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2687,11 +2687,9 @@ 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;
}
Comment thread
ericsnowcurrently marked this conversation as resolved.
Expand Down Expand Up @@ -2736,19 +2734,17 @@ 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()) {
Comment thread
skirpichev marked this conversation as resolved.
re_sum = cs_add(re_sum, value);
im_sum.hi += 0.0;
Py_DECREF(item);
continue;
}
}
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;
Expand Down