< prev index next >

src/java.base/share/classes/java/util/stream/Collectors.java

Print this page
rev 52916 : [mq]: 8214761-Bug-in-parallel-Kahan-summation-implementation-for-Doublestream-sum

@@ -712,11 +712,11 @@
     public static <T> Collector<T, ?, Double>
     summingDouble(ToDoubleFunction<? super T> mapper) {
         /*
          * In the arrays allocated for the collect operation, index 0
          * holds the high-order bits of the running sum, index 1 holds
-         * the low-order bits of the sum computed via compensated
+         * the (negative) low-order bits of the sum computed via compensated
          * summation, and index 2 holds the simple sum used to compute
          * the proper result if the stream contains infinite values of
          * the same sign.
          */
         return new CollectorImpl<>(

@@ -724,22 +724,22 @@
                 (a, t) -> { double val = mapper.applyAsDouble(t);
                             sumWithCompensation(a, val);
                             a[2] += val;},
                 (a, b) -> { sumWithCompensation(a, b[0]);
                             a[2] += b[2];
-                            return sumWithCompensation(a, b[1]); },
+                            return sumWithCompensation(a, -b[1]); },
                 a -> computeFinalSum(a),
                 CH_NOID);
     }
 
     /**
      * Incorporate a new double value using Kahan summation /
      * compensation summation.
      *
-     * High-order bits of the sum are in intermediateSum[0], low-order
-     * bits of the sum are in intermediateSum[1], any additional
-     * elements are application-specific.
+     * High-order bits of the sum are in intermediateSum[0],
+     * negative low-order bits of the sum are in intermediateSum[1],
+     * any additional elements are application-specific.
      *
      * @param intermediateSum the high-order and low-order words of the intermediate sum
      * @param value the name value to be included in the running sum
      */
     static double[] sumWithCompensation(double[] intermediateSum, double value) {

@@ -756,11 +756,11 @@
      * or more same-signed infinite values, return the
      * correctly-signed infinity stored in the simple sum.
      */
     static double computeFinalSum(double[] summands) {
         // Better error bounds to add both terms as the final sum
-        double tmp = summands[0] + summands[1];
+        double tmp = summands[0] - summands[1];
         double simpleSum = summands[summands.length - 1];
         if (Double.isNaN(tmp) && Double.isInfinite(simpleSum))
             return simpleSum;
         else
             return tmp;

@@ -830,17 +830,17 @@
     public static <T> Collector<T, ?, Double>
     averagingDouble(ToDoubleFunction<? super T> mapper) {
         /*
          * In the arrays allocated for the collect operation, index 0
          * holds the high-order bits of the running sum, index 1 holds
-         * the low-order bits of the sum computed via compensated
+         * the (negative) low-order bits of the sum computed via compensated
          * summation, and index 2 holds the number of values seen.
          */
         return new CollectorImpl<>(
                 () -> new double[4],
-                (a, t) -> { double val = mapper.applyAsDouble(t); sumWithCompensation(a, val); a[2]++; a[3]+= val;},
-                (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
+                (a, t) -> { double val = mapper.applyAsDouble(t); sumWithCompensation(a, val); a[2]++; a[3] += val; },
+                (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, -b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
                 a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),
                 CH_NOID);
     }
 
     /**
< prev index next >