合計順序を変更すると異なる結果が返されるのはなぜですか?
23.53 + 5.88 + 17.64
= 47.05
23.53 + 17.64 + 5.88
= 47.050000000000004
JavaとJavaScriptの両方が同じ結果を返します。
浮動小数点数が2進数で表される方法のために、一部の有理数(1/3 --0.333333 ...など)を正確に表すことができないことを理解しています。
要素の順序を変更するだけで結果に影響するのはなぜですか?
この質問はばかげているかもしれませんが、要素の順序を変更するだけで結果に影響するのはなぜですか?
値の大きさに基づいて、値が丸められるポイントが変更されます。私たちが見ている種類の例として、2進浮動小数点の代わりに、有効数字4桁の10進浮動小数点型を使用していて、各加算が「無限」の精度で実行されてから、次のように丸められているとしましょう。最も近い表現可能な数。ここに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に丸められます。(これは、Eric Lippertが彼の回答で指摘した問題の例です。)
右側の最初の行の値はすべての場合で同じであることに注意することが重要です-したがって、10進数(23.53、5.88、17.64)はdouble
値として正確に表されないことを理解することが重要ですが、それは上記の問題による問題のみ。
これがバイナリで起こっていることです。ご存知のように、浮動小数点値の中には、10進数で正確に表現できる場合でも、2進数で正確に表現できないものがあります。これらの3つの数字は、その事実のほんの一例です。
このプログラムでは、各数値の16進表現と各加算の結果を出力します。
public class Main{
public static void main(String args[]) {
double x = 23.53; // Inexact representation
double y = 5.88; // Inexact representation
double z = 17.64; // Inexact representation
double s = 47.05; // What math tells us the sum should be; still inexact
printValueAndInHex(x);
printValueAndInHex(y);
printValueAndInHex(z);
printValueAndInHex(s);
System.out.println("--------");
double t1 = x + y;
printValueAndInHex(t1);
t1 = t1 + z;
printValueAndInHex(t1);
System.out.println("--------");
double t2 = x + z;
printValueAndInHex(t2);
t2 = t2 + y;
printValueAndInHex(t2);
}
private static void printValueAndInHex(double d)
{
System.out.println(Long.toHexString(Double.doubleToLongBits(d)) + ": " + d);
}
}
このprintValueAndInHex
方法は、単なる16進プリンターのヘルパーです。
出力は次のとおりです。
403787ae147ae148: 23.53
4017851eb851eb85: 5.88
4031a3d70a3d70a4: 17.64
4047866666666666: 47.05
--------
403d68f5c28f5c29: 29.41
4047866666666666: 47.05
--------
404495c28f5c28f6: 41.17
4047866666666667: 47.050000000000004
最初の4つの数字でありx
、y
、z
、およびs
の進表現。IEEE浮動小数点表現では、ビット2〜12は、2進指数、つまり数値のスケールを表します。(最初のビットは符号ビットで、残りのビットは仮数です。)表される指数は、実際には2進数から1023を引いたものです。
最初の4つの数値の指数が抽出されます。
sign|exponent
403 => 0|100 0000 0011| => 1027 - 1023 = 4
401 => 0|100 0000 0001| => 1025 - 1023 = 2
403 => 0|100 0000 0011| => 1027 - 1023 = 4
404 => 0|100 0000 0100| => 1028 - 1023 = 5
追加の最初のセット
2番目の数値(y
)の大きさは小さくなります。これらの2つの数値を加算してを取得x + y
すると、2番目の数値(01
)の最後の2ビットが範囲外にシフトされ、計算に反映されません。
第二添加を追加x + y
してz
、同じ規模の2つの数値を追加します。
追加の2番目のセット
ここでx + z
は、最初に発生します。それらは同じスケールですが、スケールが大きいほど数値が大きくなります。
404 => 0|100 0000 0100| => 1028 - 1023 = 5
第二の加算は加算x + z
とy
、今3ビットから落とされるy
番号を追加します(101
)。ここでは、結果が次の浮動小数点数になるため、上向きのラウンドが必要4047866666666666
です。最初の加算4047866666666667
セットと2番目の加算セットの場合です。そのエラーは、合計のプリントアウトに表示されるほど重要です。
結論として、IEEE番号で数学演算を実行するときは注意してください。一部の表現は不正確であり、スケールが異なるとさらに不正確になります。可能であれば、同様のスケールの数値を加算および減算します。
ジョンの答えはもちろん正しいです。あなたの場合、エラーは単純な浮動小数点演算を実行して累積するエラーよりも大きくありません。ある場合にはエラーがゼロになり、別の場合には小さなエラーが発生するというシナリオがあります。それは実際にはそれほど興味深いシナリオではありません。良い質問は次のとおりです。計算の順序を変更すると、小さなエラーから(比較的)大きなエラーに変わるシナリオはありますか?答えは明白にイエスです。
たとえば、次のことを考慮してください。
x1 = (a - b) + (c - d) + (e - f) + (g - h);
vs
x2 = (a + c + e + g) - (b + d + f + h);
vs
x3 = a - b + c - d + e - f + g - h;
明らかに、正確な算術では、それらは同じです。x1とx2とx3の値が大きく異なるように、a、b、c、d、e、f、g、hの値を見つけようとするのは面白いことです。あなたがそうすることができるかどうか見てください!
これは実際にはJavaとJavascriptだけでなく、floatまたはdoubleを使用するプログラミング言語にも影響を与える可能性があります。
メモリ内では、浮動小数点はIEEE 754に沿った特別な形式を使用します(コンバーターは私よりもはるかに優れた説明を提供します)。
とにかく、これがフロートコンバーターです。
http://www.h-schmidt.net/FloatConverter/
操作の順序については、操作の「細かさ」です。
最初の行は、最初の2つの値から29.41を生成します。これにより、指数として2 ^ 4が得られます。
2行目は41.17になり、指数として2 ^ 5が得られます。
指数を増やすことで有効数字が失われ、結果が変わる可能性があります。
41.17の右端の最後のビットをオンとオフに切り替えてみてください。指数の1/2 ^ 23のような「重要でない」もので、この浮動小数点の差を引き起こすのに十分であることがわかります。
編集:有効数字を覚えている人にとって、これはそのカテゴリに分類されます。有効数字1の10 ^ 4 +4999は10 ^ 4になります。この場合、有効数字ははるかに小さくなりますが、.00000000004が付加された結果を見ることができます。
浮動小数点数は、仮数(仮数)に特定のサイズのビットを提供するIEEE754形式を使用して表されます。残念ながら、これにより、特定の数の「小数の構成要素」を操作でき、特定の小数値を正確に表すことができません。
あなたのケースで起こっていることは、2番目のケースでは、加算が評価される順序のために、加算がおそらく何らかの精度の問題に直面しているということです。値を計算していませんが、たとえば23.53 + 17.64を正確に表すことができないのに対し、23.53 +5.88は正確に表すことができます。
残念ながら、それはあなたがただ対処しなければならない既知の問題です。
それは評価の順番に関係していると思います。合計は数学の世界では当然同じですが、A + B + C = Dの代わりにバイナリの世界では、
A + B = E
E + C = D(1)
したがって、浮動小数点数が下がる可能性のある2番目のステップがあります。
順番を変えると、
A + C = F
F + B = D(2)
Reba McEntire が息子の Shelby Blackstock と共有しているクリスマスの伝統について学びましょう。
メーガン・マークルとマライア・キャリーが自然な髪の上でどのように結合したかについて、メーガンの「アーキタイプ」ポッドキャストのエピソードで学びましょう.
ハリー王子が家族、特にチャールズ王とウィリアム王子との関係について望んでいると主張したある情報源を発見してください。
ワイノナ・ジャッドが、母親のナオミ・ジャッドが亡くなってから初めての感謝祭のお祝いを主催しているときに、彼女が今では家長であることをどのように認識したかを学びましょう.
Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?
The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!
ランボルギーニの創設者であるフェルッチオランボルギーニが100歳になるのは毎日ではありません(そうです、彼は死んでいて、まだ死んでいると思います。
Appleが自動車分野に参入するという噂はかなり前から渦巻いており、AppleウォッチャーがSixtyEight Researchという会社がAppleの自動車研究開発のシェル会社である可能性が高いと判断したとき、その渦巻きは本当に渦巻いた。また、会社が購入した車は1台だけであることが知られており、その車はAppleが何を考えているかについての手がかりでいっぱいになる可能性があることも伝えています。
太陽系の外側にある架空の大きな物体である惑星Xの探索は、何十年にもわたって人間を魅了してきました。その検索の最新の章は、地球の10倍の大きさで、公転周期が15であるほど遠くにある惑星を指しています。
カムニュートンは昨日、簡単な265ヤードと3回のタッチダウンでファルコンズを引き裂き、別の素晴らしいゲームをしました。その日のハイライトは、上のタッチダウンスローでした。これは、視聴するたびにばかげているだけです。
ロシアのフィギュアスケーター、カミラ・バリエバが関与したドーピング事件が整理されているため、チームは2022年北京冬季オリンピックで獲得したメダルを待っています。
何千人ものAmazonの買い物客がMulberry Silk Pillowcaseを推奨しており、現在販売中. シルクの枕カバーにはいくつかの色があり、髪を柔らかく肌を透明に保ちます。Amazonで最大46%オフになっている間にシルクの枕カバーを購入してください
ラファイエット警察署は、「不審な男性が女性に近づいた」という複数の苦情を受けて、12 月にパデュー大学の教授の捜査を開始しました。
私たちの周りの世界と同じように、言語は常に変化しています。以前の時代では、言語の変化は数年または数十年にわたって発生していましたが、現在では数日または数時間で変化する可能性があります。
認知症を患っている 91 歳のアジア人女性が最近、47 番街のアウター サンセット地区でロメオ ロレンゾ パーハムに襲われました。伝えられるところによると、被害者はサンフランシスコの通りを歩いていたところ、容疑者に近づき、攻撃を受け、暴行を受けました。
“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.
人々にチャンスを与えることは、人生で少し遅すぎると私は信じています。寛大に。