@@ -2528,29 +2528,35 @@ typedef struct {
25282528 double lo ; /* a running compensation for lost low-order bits */
25292529} CompensatedSum ;
25302530
2531- static inline void
2532- cs_add ( CompensatedSum * v , double x )
2531+ static inline CompensatedSum
2532+ cs_from_double ( double x )
25332533{
2534- double t = v -> hi + x ;
2535- if (fabs (v -> hi ) >= fabs (x )) {
2536- v -> lo += (v -> hi - t ) + x ;
2534+ return (CompensatedSum ) {x };
2535+ }
2536+
2537+ static inline CompensatedSum
2538+ cs_add (CompensatedSum total , double x )
2539+ {
2540+ double t = total .hi + x ;
2541+ if (fabs (total .hi ) >= fabs (x )) {
2542+ total .lo += (total .hi - t ) + x ;
25372543 }
25382544 else {
2539- v -> lo += (x - t ) + v -> hi ;
2545+ total . lo += (x - t ) + total . hi ;
25402546 }
2541- v -> hi = t ;
2547+ return ( CompensatedSum ) { t , total . lo } ;
25422548}
25432549
25442550static inline double
2545- cs_to_double (CompensatedSum * v )
2551+ cs_to_double (CompensatedSum total )
25462552{
25472553 /* Avoid losing the sign on a negative result,
25482554 and don't let adding the compensation convert
25492555 an infinite or overflowed sum to a NaN. */
2550- if (v -> lo && isfinite (v -> lo )) {
2551- v -> hi += v -> lo ;
2556+ if (total . lo && isfinite (total . lo )) {
2557+ return total . hi + total . lo ;
25522558 }
2553- return v -> hi ;
2559+ return total . hi ;
25542560}
25552561
25562562/*[clinic input]
@@ -2665,18 +2671,18 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
26652671 }
26662672
26672673 if (PyFloat_CheckExact (result )) {
2668- CompensatedSum re_sum = { PyFloat_AS_DOUBLE (result )} ;
2674+ CompensatedSum re_sum = cs_from_double ( PyFloat_AS_DOUBLE (result )) ;
26692675 Py_SETREF (result , NULL );
26702676 while (result == NULL ) {
26712677 item = PyIter_Next (iter );
26722678 if (item == NULL ) {
26732679 Py_DECREF (iter );
26742680 if (PyErr_Occurred ())
26752681 return NULL ;
2676- return PyFloat_FromDouble (cs_to_double (& re_sum ));
2682+ return PyFloat_FromDouble (cs_to_double (re_sum ));
26772683 }
26782684 if (PyFloat_CheckExact (item )) {
2679- cs_add (& re_sum , PyFloat_AS_DOUBLE (item ));
2685+ re_sum = cs_add (re_sum , PyFloat_AS_DOUBLE (item ));
26802686 _Py_DECREF_SPECIALIZED (item , _PyFloat_ExactDealloc );
26812687 continue ;
26822688 }
@@ -2690,7 +2696,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
26902696 continue ;
26912697 }
26922698 }
2693- result = PyFloat_FromDouble (cs_to_double (& re_sum ));
2699+ result = PyFloat_FromDouble (cs_to_double (re_sum ));
26942700 if (result == NULL ) {
26952701 Py_DECREF (item );
26962702 Py_DECREF (iter );
@@ -2709,8 +2715,8 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
27092715
27102716 if (PyComplex_CheckExact (result )) {
27112717 Py_complex z = PyComplex_AsCComplex (result );
2712- CompensatedSum re_sum = { z .real } ;
2713- CompensatedSum im_sum = { z .imag } ;
2718+ CompensatedSum re_sum = cs_from_double ( z .real ) ;
2719+ CompensatedSum im_sum = cs_from_double ( z .imag ) ;
27142720 Py_SETREF (result , NULL );
27152721 while (result == NULL ) {
27162722 item = PyIter_Next (iter );
@@ -2719,13 +2725,13 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
27192725 if (PyErr_Occurred ()) {
27202726 return NULL ;
27212727 }
2722- return PyComplex_FromDoubles (cs_to_double (& re_sum ),
2723- cs_to_double (& im_sum ));
2728+ return PyComplex_FromDoubles (cs_to_double (re_sum ),
2729+ cs_to_double (im_sum ));
27242730 }
27252731 if (PyComplex_CheckExact (item )) {
27262732 z = PyComplex_AsCComplex (item );
2727- cs_add (& re_sum , z .real );
2728- cs_add (& im_sum , z .imag );
2733+ re_sum = cs_add (re_sum , z .real );
2734+ im_sum = cs_add (im_sum , z .imag );
27292735 Py_DECREF (item );
27302736 continue ;
27312737 }
@@ -2747,8 +2753,8 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
27472753 _Py_DECREF_SPECIALIZED (item , _PyFloat_ExactDealloc );
27482754 continue ;
27492755 }
2750- result = PyComplex_FromDoubles (cs_to_double (& re_sum ),
2751- cs_to_double (& im_sum ));
2756+ result = PyComplex_FromDoubles (cs_to_double (re_sum ),
2757+ cs_to_double (im_sum ));
27522758 if (result == NULL ) {
27532759 Py_DECREF (item );
27542760 Py_DECREF (iter );
0 commit comments