この記事では、Python を例として、浮動小数点演算でエラーが発生する理由について説明します。エラーが発生する可能性がある状況を紹介してください。そしてそれをどうやって解決するのか?お役に立てば幸いです。
[関連する推奨事項: Python3 ビデオ チュートリアル ]
コードを作成するときは、いわゆる浮動小数点エラーに遭遇することがあります。浮動小数点エラーの穴に足を踏み入れていないのであれば、それは幸運すぎるとしか言えません。
以下の Python の図を例に挙げます。0.1 0.2
は 0.3
と等しくなく、8.7 / 10
も ## と等しくありません。 #0.87、でも
0.869999…、とても奇妙です
整数 を表すために 0 と 1 をどのように使用するかについて説明しましょう。誰もがバイナリを知っておく必要があります。 101 は $2^2 2^0$ (つまり 5) を表し、
1010 は $2^3 2^1$ (つまり 10) を表します。
0000 です。 ..0000 は 0 で、最大値
1111...1111 は $2^{31} 2^{30} ... 2^1 2^0$、つまり 4294967295## を表します。
# 順列と組み合わせの観点から見ると、各ビットは 0 または 1 になる可能性があるため、変数全体の値には $2^{32}$ の可能性があり、
0 から $2 を表現できます。 ^ {23} - 1$ の間の任意の値 (エラーなし)。
浮動小数点だけです。 $2^{32}$ ほどありますが、浮動小数点数は異なります。次のように考えることができます。1 から 10 までの整数は 10 個しかありませんが、 A は無限にあります。 5.1、5.11、5.111 などの浮動小数点数のリストは無限にあります。 しかし、32 ビット空間には 23² 個の可能性しかないため、すべての浮動小数点数をこの 32 ビット空間に詰め込むために、多くの CPU メーカーがさまざまな浮動小数点数表現方法を発明してきました。 CPUごとにフォーマットが異なると面倒なので、最終的に浮動小数点演算の一般的な規格としてIEEEが発行したIEEE 754が使われ、現在のCPUもこの規格に基づいて設計されています。
IEEE 754標準化浮動小数点数 8.5 を IEEE 754 形式に変更する場合は、まず次のことを行う必要があります。正規化を行います。8.5 を 8 0.5、つまり $2^3 (\cfrac{1}{2})^1$ に分割し、それをバイナリで書き込んで
1000.1 にし、最後に $1.0001 として書き込みます。 \ に 2^3$ を掛けます。これは 10 進科学表記法によく似ています。
単精度浮動小数点数IEEE 754 では、32 ビット浮動小数点数は 3 つの部分に分割されます。符号)、指数、分数の合計は 32 ビット
符号: 左端の 1 ビット 正負の符号を表し、正の数の場合、符号は 0、それ以外の場合は 1
は 1.
の後に削除されるため、8.5 を 32 ビット形式で表現すると、次のようになります: 8 と 0.5 は両方とも 2 の累乗であるため、上記の 8.5 の例は $2^3 (\cfrac{1}{2})^1$ と表現できます。したがって、精度の問題はまったくありません。
しかし、8.9 の場合、2 のべき乗を加算する方法がないため、$1.0001110011... \times 2^3$ と表現せざるを得なくなり、約 $0.0000003$ の誤差も発生します。興味があれば、IEEE-754 Floating Point Converter の Web サイトにアクセスして試してみることができます。
#倍精度浮動小数点数
#前述の単精度浮動小数点数は、わずか 32 ビットで表されます。 IEEE 754では、誤差を小さくするために浮動小数点数を64ビットで表現することも定められており、32ビットに比べて小数部が23ビットから52ビットと2倍以上拡張されているため、当然精度は向上します。たくさん。
先ほどの 8.9 を例に挙げると、64 ビットで表現するとより正確になりますが、8.9 を 2 の累乗の合計として完全に記述することはできません。小数になります。下位 16 ビットには依然としてエラーが存在しますが、単精度エラー 0.0000003
同様の状況も # のようになります。 Python の ##1.0 は
0.999...999 に等しく、
123 も
122.999...999 に等しくなります。それらは非常に小さいので、小数に入れることができないため、バイナリ形式からは、すべてのバイナリ ビットは同じになります。
最大許容誤差 ε (イプシロン) を設定します一部の言語では、いわゆるイプシロンが提供されます。浮動小数点誤差の許容範囲内かどうかを判断するために使用されます。Python では、epsilon の値は約 $2.2e^{-16}$
#、つまり、演算中に浮動小数点エラーが原因で問題が発生するのを避けるために、
0.1 0.2 == 0.3 を 0.1 0.2 — 0.3 に書き換えることができます。 0.1 プラス 0.2 を比較します。それは 0.3 に等しいですか? <code>
もちろん、システムがイプシロンを提供しない場合は、自分でイプシロンを定義して、約 2 の -15 乗に設定することもできます。
完全に使用します計算用の 10 進法 浮動小数点エラーが発生する理由は、10 進数を 2 進数に変換するプロセスで、小数部分を仮数部にすべて詰め込むことができないためです。変換時にエラーが発生した場合は、変換する必要はなく、10 進数を使用して計算を行うだけです。
Python には 10 進数というモジュールがあり、JavaScript にも同様のパッケージがあります。ペンと紙を使って 0.1 0.2 を間違いや間違いなく計算できるのと同じように、10 進数で計算を実行するのに役立ちます。
10 進数を使用して計算すると浮動小数点数のエラーを完全に回避できますが、Decimal の 10 進数計算がシミュレートされるため、最下位レベルの CPU 回路では 2 進数が使用されます。ネイティブの浮動小数点演算よりもはるかに遅いため、すべての浮動小数点演算に Decimal を使用することはお勧めできません。
プログラミング関連の知識について詳しくは、
プログラミング入門以上が浮動小数点演算でエラーが発生する理由についての簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。