web-dev-qa-db-ja.com

浮動小数点の丸めモードを変更します

IEEE 754浮動小数点数の丸めモード*を変更する最も効率的な方法は何ですか?ポータブルC関数は素晴らしいですが、x86アセンブリを使用するソリューションも問題ありません。

*私は、最も近い方向、ゼロ方向、および正/負の無限大に向かう標準の丸めモードを参照しています

40

これは標準のCソリューションです。

_#include <fenv.h>
#pragma STDC FENV_ACCESS ON

// store the original rounding mode
const int originalRounding = fegetround( );
// establish the desired rounding mode
fesetround(FE_TOWARDZERO);
// do whatever you need to do ...

// ... and restore the original mode afterwards
fesetround(originalRounding);
_

C99のサポートがない後方プラットフォームでは、アセンブリに頼る必要があるかもしれません。この場合、x87ユニット(fldcw命令を介して)とSSE(ldmxcsr命令を介して)の両方に丸めを設定することができます。

編集MSVCのアセンブリに頼る必要はありません。代わりに(完全に非標準の)_controlfp( )を使用できます。

_unsigned int originalRounding = _controlfp(0, 0);
_controlfp(_RC_CHOP, _MCW_RC);
// do something ...
_controlfp(originalRounding, _MCW_RC);
_

_controlfp() MSDN について詳しく読むことができます。

そして、完全を期すために、丸めモードのマクロ名のデコーダーリング:

_rounding mode    C name         MSVC name
-----------------------------------------
to nearest       FE_TONEAREST   _RC_NEAR
toward zero      FE_TOWARDZERO  _RC_CHOP
to +infinity     FE_UPWARD      _RC_UP
to -infinity     FE_DOWNWARD    _RC_DOWN
_
39
Stephen Canon