3.2.10 ユーザ定義の例外ハンドラの例

この例外トラップハンドラの例は、無効演算例外でなくゼロ除算例外をオーバーライドして 1 が返されるようにします。

ARM® コンパイラ ツールチェーンでは、AArch64 ターゲット用の浮動小数点の例外のトラップはサポートされません。

これらの機能では、例外をサポートする浮動小数点モデルが必要です。 ARM コンパイラ コンパイラ 6 では、これはデフォルトで有効になっています。-ffast-math などの armclang コマンドラインオプションによって無効になります。
例として、Fortran コードを C 言語に変換する場合を考えます。Fortran における数値演算の標準では、ゼロをゼロで除算した場合の結果が 1 になると規定されていますが、IEEE 754 では無効演算となるため、デフォルトではクワイエット型の NaN が返されます。Fortran コードはこの動作に依存する可能性が高いので、コードを修正するよりも、ゼロをゼロで除算した場合に 1 が返されるようにする方が多くの場合は簡単です。
このハンドラのインストール後は、0.0 で 0.0 を除算すると 1.0 が返されるようになります。
ユーザ定義の例外ハンドラ
#include <fenv.h> #include <signal.h> #include <stdio.h> __softfp __ieee_value_t myhandler(__ieee_value_t op1, __ieee_value_t op2,                                  __ieee_edata_t edata) {     __ieee_value_t ret;     if ((edata & FE_EX_FN_MASK) == FE_EX_FN_DIV)     {         if ((edata & FE_EX_INTYPE_MASK) == FE_EX_INTYPE_FLOAT)         {             if (op1.f == 0.0 && op2.f == 0.0)             {                 ret.f = 1.0;                 return ret;             }         }          if ((edata & FE_EX_INTYPE_MASK) == FE_EX_INTYPE_DOUBLE)         {             if (op1.d == 0.0 && op2.d == 0.0)             {                 ret.d = 1.0;                 return ret;             }         }     }     /* 他のすべての無効な演算に対して、通常どおり SIGFPE を生成 */     raise(SIGFPE); } int main(void) {     float i, j, k;     fenv_t env;     fegetenv(&env);     env.statusword |= FE_IEEE_MASK_INVALID;     env.invalid_handler = myhandler;     fesetenv(&env);     i = 0.0;     j = 0.0;     k = i/j;     printf("k is %f\n", k); }
関連する概念
3.2.9 ユーザ定義の例外トラップハンドラの記述
3.2.11 シグナルによる例外トラップ処理
3.5.7 IEEE 754 浮動小数点演算で発生する例外
3.2 ARM 浮動小数点環境の制御
関連する参考文書
3.2.8 C99 インタフェースの ARM 浮動小数点コンパイラ拡張
3.2.2 ARM 浮動小数点環境を制御するための C99 互換関数
非機密扱いPDF file icon PDF 版ARM DUI0808CJ
Copyright © 2014, 2015 ARM.All rights reserved.