< 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,722 **** 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 * 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<>( --- 712,722 ---- 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 (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,745 **** (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]); }, 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. * * @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) { --- 724,745 ---- (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]); }, 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], ! * 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,766 **** * 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 simpleSum = summands[summands.length - 1]; if (Double.isNaN(tmp) && Double.isInfinite(simpleSum)) return simpleSum; else return tmp; --- 756,766 ---- * 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 simpleSum = summands[summands.length - 1]; if (Double.isNaN(tmp) && Double.isInfinite(simpleSum)) return simpleSum; else return tmp;
*** 830,846 **** 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 * 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 -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]), CH_NOID); } /** --- 830,846 ---- 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 (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 -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]), CH_NOID); } /**
< prev index next >