簡體   English   中英

為什么DoubleStream.sum()的結果與直接添加不同?

[英]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值的簡單求和(可能會出現准確性問題,正如您在第一個代碼段中所注意到的那樣),因此可能會返回更准確的結果

編輯:請注意,盡管使用DoubleStreamsum()似乎可以提供更准確的結果,但這是一個實現細節,因此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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM