Why is the result of DoubleStream.sum () different from direct adding?

I am embarrassed. If I count

System.out.println(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1); 

Then I get the result 0.9999999999999999 . But if I count

 Double sum = DoubleStream.builder().add(0.1).add(0.1).add(0.1).add(0.1).add(0.1).add(0.1).add(0.1).add(0.1).add(0.1).add(0.1).build().sum(); System.out.println(sum); 

Then I get the result 1.0 . Why is there a difference?

+5
source share
2 answers

Javadoc double java.util.stream.DoubleStream.sum () answers your question:

In particular, this method can be implemented using compensated summation or another method to reduce the error in the numerical sum compared to a simple summation of double values.

In other words, the implementation of sum() does not require a simple summation of double values ​​(which may have problems with accuracy, as you noted in your first fragment), and therefore can return a more accurate result .

EDIT: note that while using the DoubleStream sum() seems to give a more accurate result, this is an implementation detail, so it is not guaranteed by Javadoc. In addition, simply adding a double more efficient since it does not have the overhead of building a DoubleStream . You must decide whether you prefer the potential better accuracy or performance.

+10
source

To increase Eran’s response, inside DoubleStream#sum uses Kahan Summation .

Relevant Parts:

 /** * 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. * */ static double[] sumWithCompensation(double[] intermediateSum, double value) { .... 
+2
source

Source: https://habr.com/ru/post/1271687/


All Articles