29.14. fpectl
— 浮動小数点例外の制御¶
注釈
fpectl
モジュールはデフォルトではビルドされません。このモジュールの利用は推奨されておらず、熟練者以外がこのモジュールを使うのは危険です。このモジュールの制限についての詳細は、 制限と他に考慮すべきこと 節を参照してください。
ほとんどのコンピュータはいわゆるIEEE-754標準に準拠した浮動小数点演算を実行します。実際のどんなコンピュータでも、浮動小数点演算が普通の浮動小数点数では表せない結果になることがあります。例えば、次を試してください
>>> import math
>>> math.exp(1000)
inf
>>> math.exp(1000) / math.exp(1000)
nan
(上の例は多くのプラットホームで動作します。DEC Alphaは例外かもしれません。) “Inf”は”infinity(無限)”を意味するIEEE-754における特殊な非数値の値で、”nan”は”not a number(数ではない)”を意味します。ここで留意すべき点は、その計算を行うようにPythonに求めたときに非数値の結果以外に特別なことは何も起きないというです。事実、それはIEEE-754標準に規定されたデフォルトのふるまいで、それで良ければここで読むのを止めてください。
いくつかの環境では、誤った演算がなされたところで例外を発生し、処理を止めることがより良いでしょう。 fpectl
モジュールはそんな状況で使うためのものです。いくつかのハードウェア製造メーカーの浮動小数点ユニットを制御できるようにします。つまり、IEEE-754例外Division by Zero、OverflowあるいはInvalid Operationが起きたときはいつでも SIGFPE
が生成させるように、ユーザが切り替えられるようにします。あなたのpythonシステムを構成しているCコードの中へ挿入される一組のラッパーマクロと協力して、 SIGFPE
は捕捉され、Python FloatingPointError
例外へ変換されます。
fpectl
モジュールは次の関数を定義しています。また、所定の例外を発生します:
-
fpectl.
turnon_sigfpe
()¶ SIGFPE
を生成するように切り替え、適切なシグナルハンドラを設定します。
-
fpectl.
turnoff_sigfpe
()¶ 浮動小数点例外のデフォルトの処理に再設定します。
-
exception
fpectl.
FloatingPointError
¶ turnon_sigfpe()
が実行された後に、IEEE-754例外であるDivision by Zero、OverflowまたはInvalid operationの一つを発生する浮動小数点演算は、次にこの標準Python例外を発生します。
29.14.1. 例¶
以下の例は fpectl
モジュールの使用を開始する方法とモジュールのテスト演算について示しています。
>>> import fpectl
>>> import fpetest
>>> fpectl.turnon_sigfpe()
>>> fpetest.test()
overflow PASS
FloatingPointError: Overflow
div by 0 PASS
FloatingPointError: Division by zero
[ more output from test elided ]
>>> import math
>>> math.exp(1000)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
FloatingPointError: in math_1
29.14.2. 制限と他に考慮すべきこと¶
特定のプロセッサをIEEE-754浮動小数点エラーを捕らえるように設定することは、現在アーキテクチャごとの基準に基づきカスタムコードを必要とします。あなたの特殊なハードウェアを制御するために fpectl
を修正することもできます。
IEEE-754例外のPython例外への変換には、ラッパーマクロ PyFPE_START_PROTECT
と PyFPE_END_PROTECT
があなたのコードに適切な方法で挿入されていることが必要です。Python自身は fpectl
モジュールをサポートするために修正されていますが、数値解析にとって興味ある多くの他のコードはそうではありません。
fpectl
モジュールはスレッドセーフではありません。
参考
このモジュールがどのように動作するのかについてより学習するときに、ソースディストリビューションの中のいくつかのファイルは興味を引くものでしょう。インクルードファイル Include/pyfpe.h
では、このモジュールの実装について同じ長さで議論されています。 Modules/fpetestmodule.c
には、いくつかの使い方の例があります。多くの追加の例が Objects/floatobject.c
にあります。