Change floating point rounding mode
This is the standard C solution:
#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);
On backwards platforms lacking C99 support, you may need to resort to assembly. In this case, you may want to set the rounding for both the x87 unit (via the fldcw
instruction) and SSE (via the ldmxcsr
instruction).
Edit
You don't need to resort to assembly for MSVC. You can use the (totally non-standard) _controlfp( )
instead:
unsigned int originalRounding = _controlfp(0, 0);
_controlfp(_RC_CHOP, _MCW_RC);
// do something ...
_controlfp(originalRounding, _MCW_RC);
You can read more about _controlfp( ) on MSDN.
And, just for completeness, a decoder ring for the macro names for rounding modes:
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