28.16. "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例外を発生します。


28.16.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 <module>
   FloatingPointError: in math_1


28.16.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" にあります。
