--- old/src/share/classes/java/util/stream/ReduceOps.java 2013-11-19 11:34:21.000000000 -0800 +++ new/src/share/classes/java/util/stream/ReduceOps.java 2013-11-19 11:34:21.000000000 -0800 @@ -599,6 +599,62 @@ } /** + * Constructs a {@code TerminalOp} that implements a functional reduce on + * {@code double} values. + * + * @param identity the identity for the combining function + * @param operator the combining function + * @return a {@code TerminalOp} implementing the reduction + */ + public static TerminalOp + makeDoubleCompensatingSummer() { + class ReducingSink + implements AccumulatingSink, Sink.OfDouble { + private double sum; + private double sumCompensation; + + /** + * 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; + } + + @Override + public void begin(long size) { + sum = 0.0; + sumCompensation = 0.0; + } + + @Override + public void accept(double t) { + sumWithCompensation(t); + } + + @Override + public Double get() { + return sum; + } + + @Override + public void combine(ReducingSink other) { + accept(other.sum); + accept(other.sumCompensation); + } + } + return new ReduceOp(StreamShape.DOUBLE_VALUE) { + @Override + public ReducingSink makeSink() { + return new ReducingSink(); + } + }; + } + + /** * Constructs a {@code TerminalOp} that implements a mutable reduce on * {@code double} values. *