@@ -2528,29 +2528,35 @@ typedef struct {
2528
2528
double lo ; /* a running compensation for lost low-order bits */
2529
2529
} CompensatedSum ;
2530
2530
2531
- static inline void
2532
- cs_add ( CompensatedSum * v , double x )
2531
+ static inline CompensatedSum
2532
+ cs_from_double ( double x )
2533
2533
{
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 ;
2537
2543
}
2538
2544
else {
2539
- v -> lo += (x - t ) + v -> hi ;
2545
+ total . lo += (x - t ) + total . hi ;
2540
2546
}
2541
- v -> hi = t ;
2547
+ return ( CompensatedSum ) { t , total . lo } ;
2542
2548
}
2543
2549
2544
2550
static inline double
2545
- cs_to_double (CompensatedSum * v )
2551
+ cs_to_double (CompensatedSum total )
2546
2552
{
2547
2553
/* Avoid losing the sign on a negative result,
2548
2554
and don't let adding the compensation convert
2549
2555
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 ;
2552
2558
}
2553
- return v -> hi ;
2559
+ return total . hi ;
2554
2560
}
2555
2561
2556
2562
/*[clinic input]
@@ -2665,18 +2671,18 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
2665
2671
}
2666
2672
2667
2673
if (PyFloat_CheckExact (result )) {
2668
- CompensatedSum re_sum = { PyFloat_AS_DOUBLE (result )} ;
2674
+ CompensatedSum re_sum = cs_from_double ( PyFloat_AS_DOUBLE (result )) ;
2669
2675
Py_SETREF (result , NULL );
2670
2676
while (result == NULL ) {
2671
2677
item = PyIter_Next (iter );
2672
2678
if (item == NULL ) {
2673
2679
Py_DECREF (iter );
2674
2680
if (PyErr_Occurred ())
2675
2681
return NULL ;
2676
- return PyFloat_FromDouble (cs_to_double (& re_sum ));
2682
+ return PyFloat_FromDouble (cs_to_double (re_sum ));
2677
2683
}
2678
2684
if (PyFloat_CheckExact (item )) {
2679
- cs_add (& re_sum , PyFloat_AS_DOUBLE (item ));
2685
+ re_sum = cs_add (re_sum , PyFloat_AS_DOUBLE (item ));
2680
2686
_Py_DECREF_SPECIALIZED (item , _PyFloat_ExactDealloc );
2681
2687
continue ;
2682
2688
}
@@ -2690,7 +2696,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
2690
2696
continue ;
2691
2697
}
2692
2698
}
2693
- result = PyFloat_FromDouble (cs_to_double (& re_sum ));
2699
+ result = PyFloat_FromDouble (cs_to_double (re_sum ));
2694
2700
if (result == NULL ) {
2695
2701
Py_DECREF (item );
2696
2702
Py_DECREF (iter );
@@ -2709,8 +2715,8 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
2709
2715
2710
2716
if (PyComplex_CheckExact (result )) {
2711
2717
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 ) ;
2714
2720
Py_SETREF (result , NULL );
2715
2721
while (result == NULL ) {
2716
2722
item = PyIter_Next (iter );
@@ -2719,13 +2725,13 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
2719
2725
if (PyErr_Occurred ()) {
2720
2726
return NULL ;
2721
2727
}
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 ));
2724
2730
}
2725
2731
if (PyComplex_CheckExact (item )) {
2726
2732
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 );
2729
2735
Py_DECREF (item );
2730
2736
continue ;
2731
2737
}
@@ -2747,8 +2753,8 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
2747
2753
_Py_DECREF_SPECIALIZED (item , _PyFloat_ExactDealloc );
2748
2754
continue ;
2749
2755
}
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 ));
2752
2758
if (result == NULL ) {
2753
2759
Py_DECREF (item );
2754
2760
Py_DECREF (iter );
0 commit comments