2

多くのブログ投稿でこのバグを見てきました: http://atifsiddiqui.blogspot.com/2010/11/windows-calculator-bug.html

このバグはコードのバグですか、それとも数学的な不正確さですか?

本当にバグなのか疑問に思っています。何年も検出されなかったのはなぜですか?

カスタム カリキュレータ プログラムでこのようなことが起こらないようにするには、どうすればよいですか。

4

7 に答える 7

6

はい、バグです。技術的な説明 (素人にはほとんど受け入れられない) があるという事実は、それがバグであることを免れるものではありません。それがバグでない場合は、「これは機能である」か、またはシステムの制限であると主張しています。

それを解決するには、すべての結果を許容可能な精度レベルに丸めて、非常に小さな誤差を取り除くことをお勧めします。他の回答が示唆するように、問題は、電卓で「4」の平方根が「2」ではなく、2 に非常に近い数値であることです。これを解決するには、結果を小数点以下 10、20、30 桁に丸めます。あなたが余裕があるものは何でも。

ユーザーが浮動小数点演算の制限にアクセスできないように、どの計算機エンジンも、アクセス可能な精度レベルを十分に上回る精度レベルを基礎とする必要があると主張します。この道をたどると、「精度」の 1 つの形式が失われますが、計算機が小数点以下 n 桁まで正確であると述べているだけです。特にこの問題が解決される場合は、許容範囲を超えています。

しかし、それは本当に大したことではありませんね。


余談ですが、私はかつて、複利の金利を計算することになっているソフトウェアをベンダーが提供する金融アプリケーションに取り組んだことがあります。彼らの計算は常にオフでした。彼らはそれが「浮動小数点演算によるもの」であると主張し、この問題について私を教育しようとしました。しかし、彼らのアルゴリズムはかなり外れていました。ドル金額に複利の金利を適用する場合、各反復 (日、週、月、年など) ごとに常に合計を四捨五入します状況に応じて、最も近いドル、最も近いセント、または最も近い 100 分の 1 セントに四捨五入される場合がありますが、これは定量化可能な金額であり、毎年 100 万分の 1 セントを複利計算することはありません。これは、本質的に計算の丸め誤差を回避したい場合に取るべきアプローチです。

于 2010-12-13T11:59:21.880 に答える
3

@Kirk Broadhurstに同意します。これは、sqrt(4)-2の結果が厳密に0であるのに対し、Calcは異なる(非常に近い)結果をもたらすため、技術的にはバグです。通常、私たちがこの不正確さで生きることができるという事実は、ここでは無関係です。厳密に言えば、プログラマーはこの種の問題を解決するためにさまざまなアプローチを模索すべきでした。

IMHO、ここで多くの人が見落としているのは、4と2がIEEE浮動小数点形式で正確に表現できるということです。2の自然な累乗であるため、無限の精度で表現できるため、FP形式を非難する議論も無関係です。この問題は、FPストレージ形式ではなく、sqrt()関数アルゴリズムに起因します。

于 2010-12-13T15:00:50.003 に答える
3

他の人が言っているように、これはバグではなく、コンピューターが内部で浮動小数点数を表し、浮動小数点演算を処理する方法に関連しています。あなたと私は浮動小数点演算を考えていませんが、コンピューターは考えています。そして、その「浮動小数点」は、10 進数ではなく 2 進数を指します。

返される数値は、実際には 0に非常に近い値です (これは、「正しい」小数の答えであることに誰もが同意できると思います)。sqrt 関数自体が 2 に非常に近い数値を返しましたが、浮動小数点型の制限により、この数値を正確に2 として内部に格納できませんでした。出力は数値「2」でした。これは、電卓が表示目的で四捨五入しただけで、「2」が期待した答えであることがわかっているためです。しかし、内部に保存された の表現から 2 を引いてsqrt(4)も、正確に 0 にはなりません。内部に保存された数値が正確に 2 ではないからです。

すべてのプログラマーは、この動作 (特に、「精度」と「2 進数から 10 進数への変換」に関するセクション) と、浮動小数点演算に関するその他の気が遠くなるような詳細について説明している"What Every Computer Scientist Should Know About Floating-Point Arithmetic"を実際に読む必要があります。コンピュータが数値を浮動小数点型として内部的に表現する方法。

于 2010-12-13T11:24:28.333 に答える
2

その一般的な浮動小数点の問題。たとえば、1/3aqnd を使用し3て浮動小数点で乗算すると、正確には1返されませんが0.9999999999999999999999、 、または1.000000000000000000001. Windows 電卓は、いくつかのアルゴリズムを使用して、先ほど説明したようなケースを最小限に抑えようとしましたが、すべての特殊なケースを処理できなかった可能性があります....

すべてではなく一部のケースを処理するため、正確にはバグではなく、ユーザビリティの問題です..

于 2010-12-13T11:25:01.353 に答える
1

calcは実際には任意の精度の数学を使用するため、通常の浮動小数点の問題よりも少し複雑です。ただし、レイモンド・チェンが述べているように、基本的な操作には無限の精度しか使用されていないようです。

現在、Calcの内部計算は、基本操作(加算、減算、乗算、除算)では無限の精度で、高度な操作(平方根、超越演算子)では32桁の精度で実行されます。

したがって、おそらく平方根は実際には2に非常に近い値になりますが、2として表示されますが、正確に減算すると、0として表示されない0に非常に近い数値が残りますが、これはバグです。 ?依存します。

于 2010-12-13T12:46:22.740 に答える
1

これはバグではありません(コンピュータはこのように動作します!)。SO では、このトピックに関する多くの質問があります。たとえば、「JavaScript 数学が壊れている」を検索します。

経験豊富なコンピューター ユーザーは、-8.1648465955514287168521180122928e-39 が実質的にゼロと同じであることも認識する必要があります。

このようなことを避けたい場合は、文字列に変換するときにすべての結果を丸めることができます。-8.1648465955514287168521180122928e-39 は 0 に丸められます。ただし、非常に高度な計算機を作成している場合、たとえばプランク定数を操作できる場合、これは機能しません (これを行った場合、プランク定数はゼロに等しいと見なされます)。 、これは悪いです)。非常に良い代替手段は、記号数学を使用することですが、電卓を書くのに数分もかからず、数か月/数年かかります...

于 2010-12-13T11:23:53.450 に答える
0

2純粋な推測では、計算機が平方根の結果を正確に得られないためだと思います(根の計算方法によって異なります)。ただし、結果がゼロから離れている場合は、単に表示を丸めます。ただし、数値がゼロに近い場合は、正確な結果が表示されます。

独自の計算機の場合、単純にそのような高い精度が得られない (プログラミング言語が提供する通常の数学機能を使用する場合には通常得られない) だけでは、そのような結果は得られないでしょう。

于 2010-12-13T11:21:02.777 に答える