src/share/classes/java/util/stream/DoublePipeline.java

Print this page

        

*** 375,386 **** evaluate(ForEachOps.makeDouble(consumer, true)); } @Override public final double sum() { ! // TODO: better algorithm to compensate for errors ! return reduce(0.0, Double::sum); } @Override public final OptionalDouble min() { return reduce(Math::min); --- 375,393 ---- evaluate(ForEachOps.makeDouble(consumer, true)); } @Override public final double sum() { ! double[] summation = collect(() -> new double[2], ! (ll, d) -> { ! Collectors.sumWithCompensation(ll, d); ! }, ! (ll, rr) -> { ! Collectors.sumWithCompensation(ll, rr[0]); ! Collectors.sumWithCompensation(ll, rr[1]); ! }); ! return summation[0]; } @Override public final OptionalDouble min() { return reduce(Math::min);
*** 389,411 **** @Override public final OptionalDouble max() { return reduce(Math::max); } @Override public final OptionalDouble average() { ! double[] avg = collect(() -> new double[2], ! (ll, i) -> { ! ll[0]++; ! ll[1] += i; }, (ll, rr) -> { ! ll[0] += rr[0]; ! ll[1] += rr[1]; }); return avg[0] > 0 ! ? OptionalDouble.of(avg[1] / avg[0]) : OptionalDouble.empty(); } @Override public final long count() { --- 396,428 ---- @Override public final OptionalDouble max() { return reduce(Math::max); } + /** + * {@inheritDoc} + * + * @implNote The {@code double} format can represent all + * consecutive integers in the range -2<sup>53</sup> to + * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup> + * values, the divisor in the average computation will saturate at + * 2<sup>53</sup>, leading to additional numerical errors. + */ @Override public final OptionalDouble average() { ! double[] avg = collect(() -> new double[3], ! (ll, d) -> { ! ll[2]++; ! Collectors.sumWithCompensation(ll, d); }, (ll, rr) -> { ! Collectors.sumWithCompensation(ll, rr[0]); ! Collectors.sumWithCompensation(ll, rr[1]); ! ll[2] += rr[2]; }); return avg[0] > 0 ! ? OptionalDouble.of(avg[0] / avg[2]) : OptionalDouble.empty(); } @Override public final long count() {