src/share/classes/java/util/DoubleSummaryStatistics.java

Print this page

        

@@ -61,10 +61,11 @@
  * @since 1.8
  */
 public class DoubleSummaryStatistics implements DoubleConsumer {
     private long count;
     private double sum;
+    private double sumCompensation; // Low order bits of sum
     private double min = Double.POSITIVE_INFINITY;
     private double max = Double.NEGATIVE_INFINITY;
 
     /**
      * Construct an empty instance with zero count, zero sum,

@@ -79,11 +80,11 @@
      * @param value the input value
      */
     @Override
     public void accept(double value) {
         ++count;
-        sum += value;
+        sumWithCompensation(value);
         min = Math.min(min, value);
         max = Math.max(max, value);
     }
 
     /**

@@ -93,16 +94,28 @@
      * @param other another {@code DoubleSummaryStatistics}
      * @throws NullPointerException if {@code other} is null
      */
     public void combine(DoubleSummaryStatistics other) {
         count += other.count;
-        sum += other.sum;
+        sumWithCompensation(other.sum);
+        sumWithCompensation(other.sumCompensation);
         min = Math.min(min, other.min);
         max = Math.max(max, other.max);
     }
 
     /**
+     * Incorporate a new double value using Kahan summation /
+     * compensation summation.
+     */
+    private void sumWithCompensation(double value) {
+        double tmp = value - sumCompensation;
+        double velvel = sum + tmp; // Little wolf of rounding error
+        sumCompensation = (velvel - sum) - tmp;
+        sum = velvel;
+    }
+
+    /**
      * Return the count of values recorded.
      *
      * @return the count of values
      */
     public final long getCount() {