float_control pragma

関数の浮動小数点動作を指定します。

構文

#pragma float_control


[オプション]


精度の高い浮動小数点セマンティクスを有効 (on) または無効 (off) にするかどうかを指定します。 /fp:precise コンパイラ オプションの違いについては、「解説」セクションを参照してください。 省略可能な push トークンは、float_control の現在の設定を内部コンパイラ スタックにプッシュします。


浮動小数点例外セマンティクスを有効 (on) または無効 (off) にするかどうかを指定します。 省略可能な push トークンは、float_control の現在の設定を内部コンパイラ スタックにプッシュします。

except は、preciseon に設定されている場合のみ on に設定できます。

push
現在の float_control 設定を内部コンパイラ スタックにプッシュします。

pop
内部コンパイラ スタックの最上部から float_control 設定を削除し、それを新しい float_control 設定にします。

解説

float_controlpragma には、/fp コンパイラ オプションと同じ動作はありません。 float_controlpragma は、浮動小数点の動作の一部のみを制御します。 fp_contract ディレクティブと fenv_accesspragma ディレクティブは、/fp コンパイラ オプションを再作成するには組み合わせる必要があります。 次の表は、各コンパイラ オプションの同等の pragma 設定を示しています。

オプション float_control(precise, *) float_control(except, *) fp_contract(*) fenv_access(*)
/fp:strict on on off on
/fp:precise on off off* off
/fp:fast off off on off

* Visual Studio 2022 より前の Visual Studio のバージョンでは、/fp:precise の既定の動作は fp_contract(on) です。

オプション float_control(precise, *) float_control(except, *) fp_contract(*) fenv_access(*)
/fp:strict on on off on
/fp:precise on off off off
/fp:fast off off on off

つまり、/fp:fast/fp:precise/fp:strict の各コマンド ライン オプションをエミュレートするには、複数の pragma ディレクティブを組み合わせて使用する必要がある場合があります。

float_controlfenv_access 浮動小数点 pragma ディレクティブを組み合わせて使用する方法には、制限があります。

  • float_control を使用して excepton に設定できるのは、正確なセマンティクスが有効になっている場合のみです。 正確なセマンティクスは、float_control または pragma のいずれかによって、または /fp:precise/fp:strict コンパイラ オプションを使用して有効にできます。

  • float_controlpragma を使用して、または /fp:except コンパイラ オプションのいずれであっても、例外セマンティクスが有効になっている場合は、float_control を使用して precise をオフにすることはできません。

  • fenv_access は、float_controlpragma またはコンパイラ オプションのどちらによっても、正確なセマンティクスが有効になっていない限り、有効にすることはできません。

  • float_control を使用して、fenv_access が有効になっているときに precise をオフにすることはできません。

これらの制限は、一部の浮動小数点 pragma ディレクティブの順序が重要なことを意味します。 pragma ディレクティブを使用して高速モデルから厳密なモデルに移動するには、次のコードを使用します。

#pragma float_control(precise, on)  // enable precise semantics
#pragma fenv_access(on)             // enable environment sensitivity
#pragma float_control(except, on)   // enable exception semantics
#pragma float_control(precise, on)  // enable precise semantics
#pragma fenv_access(on)             // enable environment sensitivity
#pragma float_control(except, on)   // enable exception semantics
#pragma fp_contract(off)            // disable contractions

float_controlpragma を使用して厳密なモデルから高速モデルに移動するには、次のコードを使用します。

#pragma float_control(except, off)  // disable exception semantics
#pragma fenv_access(off)            // disable environment sensitivity
#pragma float_control(precise, off) // disable precise semantics
#pragma fp_contract(on)             // enable contractions

オプションが指定されていない場合、float_control は効果がありません。

float_control ディレクティブは、precise または except をオンにすると縮約を無効にします。 float_control を使用して、precise または except をオフにすると、前の設定の縮約が復元されます。 fp_contractpragma ディレクティブを使用して、縮約に対するコンパイラの動作を変更できます。 float_control(push)float_control(pop)float_control 設定の一部として縮約の設定を内部コンパイラ スタックにプッシュおよびポップします。 この動作は、Visual Studio 2022 での新機能です。 以前のコンパイラ バージョンの float_control ディレクティブは、縮約設定に影響を与えませんでした。

次のサンプルは、 pragmafloat_control を使用してオーバーフロー浮動小数点例外をキャッチする方法を示しています。

// pragma_directive_float_control.cpp
// compile with: /EHa
#include <stdio.h>
#include <float.h>

double func( ) {
   return 1.1e75;
}

#pragma float_control (except, on)

int main( ) {
   float u[1];
   unsigned int currentControl;
   errno_t err;

   err = _controlfp_s(&currentControl, ~_EM_OVERFLOW, _MCW_EM);
   if (err != 0)
      printf_s("_controlfp_s failed!\n");

   try  {
      u[0] = func();
      printf_s ("Fail");
      return(1);
   }

   catch (...)  {
      printf_s ("Pass");
      return(0);
   }
}
Pass

関連項目

pragma ディレクティブと __pragma および _Pragma キーワード
fenv_access pragma
fp_contract pragma