![](/img/trans.png)
[英]Is Java-8's DoubleStream.sum() method stable when run in parallel?
[英]Why does DoubleStream.sum()'s result differ from straight addition?
我很迷惑。 如果我計算
System.out.println(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1);
然后我得到0.9999999999999999
的結果。 但是,如果我計算
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);
然后我得到1.0
的結果。 為什么會有區別?
雙java.util.stream.DoubleStream.sum()的Javadoc回答了你的問題:
特別地,該方法可以使用補償求和或其他技術來實現,以減少與雙值的簡單求和相比的數值和中的誤差界限。
換句話說, sum()
的實現不必使用double值的簡單求和(可能會出現准確性問題,正如您在第一個代碼段中所注意到的那樣),因此可能會返回更准確的結果 。
編輯:請注意,盡管使用DoubleStream
的sum()
似乎可以提供更准確的結果,但這是一個實現細節,因此Javadoc無法保證。 此外,簡單的double
添加更有效,因為它沒有構造DoubleStream
的開銷。 你必須決定你是否更喜歡潛在的更好的准確性或性能。
為了增加Eran的答案,內部DoubleStream#sum
使用Kahan Summation 。
相關部分:
/**
* 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) { ....
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.