広く使用されているプログラミング言語である Python は、数値計算タスクに優れていますが、浮動小数点演算によってもたらされる課題を免れないわけではありません。 Python の浮動小数点数は実数の近似値であるため、 丸め誤差、精度の低下、キャンセル それは計算を狂わせる可能性があります。我々はできる 奇妙な結果を探してこれらのエラーを見つけます そしてツールを使ってnumpy.finfo>に モニターの精度 。いくつかの注意と巧妙なトリックを使えば、次のことが可能になります。 これらのエラーをチェックしてください そして、Python の計算が信頼できるものであることを確認します。この記事では、浮動小数点エラーの複雑さを探ります。 パイソン 。
浮動小数点数とは何ですか?
浮動小数点数は、コンピュータで実数を表現する効率的な方法です。これらは 3 つの部分で構成されます。
- 重要な: 数値を表す実際の数字 (例: 3.14159)
- 指数: 仮数部を左または右に何桁シフトするかを指定します (例: 3.14159 x 10^-2 の -2)
- ベース: 通常、コンピュータの場合は 2、数値が内部でどのように表現されるかを決定します。
浮動小数点エラーが発生するのはなぜですか?
浮動小数点エラーは、コンピュータが有限数のビットを使用して実数を格納するために発生し、近似や潜在的な不正確さにつながります。浮動小数点数には固有の制限があります。
- 有限精度: 仮数部に格納できる桁数は限られているため、 丸め誤差 正確な小数を表す場合。
- 精度の低下: 加算や減算などの演算により精度がさらに低下し、丸めの効果がさらに悪化する可能性があります。
- アンダーフロー/オーバーフロー: 極端に小さい数値または大きい数値は表現可能な範囲を超えてしまう可能性があり、 アンダーフロー (ゼロになる)または オーバーフロー (無限大になります)。
浮動小数点エラーの種類
a) 丸め誤差: 最も一般的なものは、浮動小数点数の制限された精度に適合するように正確な小数を近似する必要がある場合に発生します。
b) 精度の損失: 後続の操作により丸め誤差が徐々に蓄積され、最終結果が大幅に不正確になる可能性があります。
c) 壊滅的なキャンセル: 反対の符号を持つほぼ等しい数値を減算すると、それらの有効数字が相殺され、小さくて不正確な結果が残ります。
d) オーバーフロー/アンダーフロー: これらは、計算が浮動小数点値の表現可能な範囲を超えた場合に発生し、不正確または無意味な結果をもたらします。
テキストの回り込み用のCSS
浮動小数点エラーの検出
- 予期せぬ結果を観察する: 計算値と期待される結果を比較したり、データを視覚化すると、エラーによって引き起こされることが多い不一致が明らかになることがあります。
- 次のようなライブラリを使用する
numpy.finfo>: ような図書館numpy>のようなツールを提供しますfinfo>さまざまな float データ型の精度と制限を確認します。
Python 浮動小数点エラー
ここでは、Python の浮動小数点エラーを示すさまざまな種類の例について説明します。
10 進数から 2 進数への変換における精度の損失
この例では、10 進数 0.1 が 2 進数に変換されます。 0.1 の無限バイナリ拡張により、有限数のビットのみが使用されるため、精度が失われます。
Python3
decimal_number>=> 0.1> binary_representation>=> format>(decimal_number,>'.30f'>)># 30 decimal places> print>(f>'Decimal: {decimal_number}
Binary: {binary_representation}'>)> |
>
>
出力:
Decimal: 0.1 Binary: 0.100000000000000005551115123126>
丸め誤差
ここでは、1/3 を 3 回加算した結果は 1.0 になると予想されます。ただし、1/3 を表す際の丸め誤差により、合計が正確に 1.0 にならない場合があります。
Python3
result>=> 1.0> /> 3.0> sum_result>=> result>+> result>+> result> print>(f>'Expected Result: 1.0
Actual Result: {sum_result}'>)> |
>
>
出力:
Expected Result: 1.0 Actual Result: 1.0>
反復計算における累積誤差
この例では、反復計算で累積誤差がどのように発生するかを示します。浮動小数点精度の制限により、0.1 を 10 回加算しても正確な結果が 1.0 にならない場合があります。
Python3
total>=> 0.0> for> i>in> range>(>10>):> >total>+>=> 0.1> print>(f>'Expected Result: 1.0
Actual Result: {total}'>)> |
>
>
arpコマンド
出力:
Expected Result: 1.0 Actual Result: 0.9999999999999999>
比較の問題
この場合、0.1 と 0.2 の合計を 0.3 と比較すると、期待した値が得られない可能性があります。True>この結果は、浮動小数点数に固有の不正確さによるものです。
Python3
a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a}
b: {b}
Equal: {a == b}'>)> |
>
>
出力:
a: 0.30000000000000004 b: 0.3 Equal: False>
計算で予期しない結果が発生する
ここで、1e16>合計から(1e16 + 1)>は 1 を返すことが期待されますが、浮動小数点エラーにより、結果が正確に 1 にならない場合があります。
Python3
a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a}
b: {b}
Equal: {a == b}'>)> |
>
>
出力:
Expected Result: 1 Actual Result: 0.0>
浮動小数点精度を理解する
ここでは浮動小数点の精度を理解します: Python の 1.2 – 1.0 の異常 -
表現の課題
知られているように、1.2 – 1.0 = 0.2。しかし、Python で同じことを実行しようとすると、その結果に驚くでしょう。
>>> 1.2 - 1.0>>
出力:
0.199999999999999996>
これは Python のバグであると考えられるかもしれませんが、そうではありません。これは Python とはほとんど関係がなく、基盤となるプラットフォームが浮動小数点数を処理する方法に大きく関係します。これは、システム内部で浮動小数点数を処理するときに発生する通常のケースです。これは、10 進数を表すために固定数の 2 進数を使用する浮動小数点数の内部表現で発生する問題です。一部の 10 進数を 2 進数で表現するのは難しいため、多くの場合、小さな丸め誤差が生じます。 10 進数の数学でも同様のケースが知られていますが、多くの結果は固定された 10 進数の桁数では表現できません。 例
10 / 3 = 3.33333333.......>
この場合、1.2 を例にとると、0.2 を 2 進数で表すと、0.00110011001100110011001100……というようになります。この無限の 10 進数を内部的に保存するのは困難です。通常、float オブジェクトの値は固定精度の 2 進浮動小数点で格納されます ( 通常は53ビット )。そこで私たちは代表します 1.2 内部的には、
1.0011001100110011001100110011001100110011001100110011>
これは次とまったく同じです:
1.1999999999999999555910790149937383830547332763671875>
浮動小数点エラーの処理
ここでは、Python で浮動小数点エラーを処理する方法の別の例について説明します。
特定の小数点以下の桁への四捨五入
結果を特定の小数点以下の桁 (2 など) に丸めることにより、小さな浮動小数点誤差の影響を軽減できます。
多態性
Python3
result>=> 1.2> -> 1.0> rounded_result>=> round>(result,>2>)> print>(f>'Original Result: {result}
Rounded Result: {rounded_result}'>)> |
>
>
出力:
Original Result: 0.19999999999999996 Rounded Result: 0.2>
高精度のための Decimal クラスの使用
のdecimal>モジュールが提供するのは、Decimal>クラスを使用して、より高精度の演算が可能になります。精度を設定するにはgetcontext().prec>特定の計算の精度を管理するのに役立ちます
Python3
from> decimal>import> Decimal, getcontext> getcontext().prec>=> 4> # Set precision to 4 decimal places> result>=> Decimal(>'1.2'>)>-> Decimal(>'1.0'>)> print>(f>'High Precision Result: {result}'>)> |
>
>
出力:
High Precision Result: 0.2>
分数を使用した正確な表現
のfractions>モジュールを使用すると、浮動小数点エラーを回避して正確な分数表現を操作できるようになります。
Python3
from> fractions>import> Fraction> result>=> Fraction(>'1.2'>)>-> Fraction(>'1.0'>)> print>(f>'Exact Fractional Result: {result}'>)> |
>
>
マルチプレクサ
出力:
Exact Fractional Result: 1/5>
10 進数による中間結果の処理
使用Decimal>float に戻す前に累積誤差を最小限に抑えるための中間計算用のクラス。
Python3
from> decimal>import> Decimal, getcontext> getcontext().prec>=> 6> # Set precision to 6 decimal places> intermediate_result>=> Decimal(>'1.2'>)>-> Decimal(>'1.0'>)> final_result>=> float>(intermediate_result)># Convert back to float if needed> print>(f>'Intermediate Result: {intermediate_result}
Final Result: {final_result}'>)> |
>
>
出力:
Intermediate Result: 0.2 Final Result: 0.2>
結論
それでも、なぜだろうと考えているのですか Pythonはこの問題を解決していません 、実際にはPythonとは何の関係もありません。これは、基盤となる C プラットフォームが浮動小数点数を処理する方法であるため発生します。最終的には不正確になり、常に固定桁数の文字列として数値を書き込むことになります。これはバイナリ浮動小数点の性質そのものであることに注意してください。これはバグでもありません。 パイソン または C 、そしてそれはコードのバグでもありません。ハードウェアの浮動小数点演算をサポートするすべての言語で同様の動作が見られますが、一部の言語ではデフォルトまたはすべての出力モードで違いが表示されない場合があります)。正確な精度が必要な数学の問題を扱う場合、または条件文内で使用する場合は、この動作を考慮する必要があります。チェック 浮動小数点 このような動作の詳細については、Python ドキュメントのセクションを参照してください。
よくある質問(FAQ)
1. Python の浮動小数点エラーとは何ですか?
Python の浮動小数点エラーとは、バイナリベースのシステムで実数を表現する際の制限から生じる、浮動小数点数を処理する際の期待される結果と実際の結果との間の相違を指します。
2. どして 1.2 - 1.0> 等しくない 0.2> Pythonで?
この不一致は、10 進数を 2 進数で表現する際に固有の課題が原因です。内部バイナリ表現中に丸めエラーが発生し、予期しない結果が発生します。
3. 浮動小数点エラーは Python のバグですか?
いいえ、これは Python のバグではありません。これは、浮動小数点数の内部表現方法に関連するコンピューティングにおける一般的な問題です。 Python は、浮動小数点演算に関する IEEE 754 標準に準拠しています。
4. 浮動小数点の結果を特定の小数点以下の桁に四捨五入するにはどうすればよいですか?
使用できます
round()>浮動小数点の結果を特定の小数点以下の桁に丸める関数。例えば、rounded_result = round(result, 2)>。
5. とは何ですか decimal> モジュール、そして浮動小数点エラーの処理にどのように役立つのでしょうか?
の
decimal>モジュールが提供するのは、Decimal>より高精度の演算を行うためのクラス。精度の設定と使用Decimal>浮動小数点エラーを軽減するのに役立ちます。