1. ホーム

[解決済み】sumの順番を変えると違う結果になるのはなぜですか?

2022-03-29 11:07:18

質問

sumの順番を変えると、なぜ違う結果になるのですか?

23.53 + 5.88 + 17.64 = 47.05

23.53 + 17.64 + 5.88 = 47.050000000000004

両方 ジャワ ジャバスクリプト は同じ結果を返します。

浮動小数点数の2進数の表現方法の関係で、一部の有理数( 1/3 - 0.333333... のように。 を正確に表現することができません。

なぜ、要素の順番を変えるだけで結果に影響が出るのでしょうか?

どのように解決するのですか?

<ブロッククオート

くだらない質問かもしれませんが、なぜ要素の順番を変えるだけで結果に影響が出るのでしょうか?

値の大きさに応じて、丸めるポイントを変えるのです。の例として 種類 バイナリ浮動小数点の代わりに、有効数字4桁の10進浮動小数点を使用し、各加算をquot;infinite"の精度で実行した後、最も近い表現可能な数字に丸めたと仮定してみましょう。ここに2つの合計があります。

1/3 + 2/3 + 2/3 = (0.3333 + 0.6667) + 0.6667
                = 1.000 + 0.6667 (no rounding needed!)
                = 1.667 (where 1.6667 is rounded to 1.667)

2/3 + 2/3 + 1/3 = (0.6667 + 0.6667) + 0.3333
                = 1.333 + 0.3333 (where 1.3334 is rounded to 1.333)
                = 1.666 (where 1.6663 is rounded to 1.666)

非整数でなくても問題ありません。

10000 + 1 - 10000 = (10000 + 1) - 10000
                  = 10000 - 10000 (where 10001 is rounded to 10000)
                  = 0

10000 - 10000 + 1 = (10000 - 10000) + 1
                  = 0 + 1
                  = 1

このことは、重要な部分が、限られた数の 有効数字 - の数に限りがあるのではなく 小数点以下の桁数 . 小数点以下の桁数が常に同じであれば、少なくとも足し算と引き算では、(値がオーバーフローしない限り)問題ないだろう。問題は、大きな数字になると、小さな情報が失われてしまうことです。この場合、10001は10000に丸められ、10001は10000になります。(これは、以下のような問題の一例です。 Eric Lippertが回答で指摘した .)

右辺の1行目の値は、どのような場合でも同じであることに注意してください。つまり、10進数(23.53, 5.88, 17.64)が、正確に double という値がありますが、これは上に示したような問題があるからこその問題です。