Efficiently Modifying Floating-Point Rounding in C and x86 Assembly
IEEE 754 floating-point numbers offer various rounding modes, such as nearest, zero, positive infinity, and negative infinity. Modifying the rounding mode enables precise control over the decimal representation of results.
C Solution
The C standard library provides a portable solution for altering rounding modes through the fesetround() function:
#include <fenv.h> #pragma STDC FENV_ACCESS ON int main() { // Save the original rounding mode int originalRounding = fegetround(); // Set the desired rounding mode (e.g., to zero) fesetround(FE_TOWARDZERO); // Perform operations with the adjusted rounding mode // Restore the original rounding mode fesetround(originalRounding); return 0; }
x86 Assembly Solution
For platforms without C99 support, x86 assembly can be used to modify both the x87 unit and SSE rounding modes:
; x87 unit fldcw [new rounding mode] ; e.g., FNINIT to nearest ; SSE ldmxcsr [new rounding mode] ; e.g., MXCSR_RND_NEAREST
Microsoft Visual C
MSVC offers the non-standard _controlfp() function for this purpose:
#include <math.h> int main() { // Save the original rounding mode unsigned int originalRounding = _controlfp(0, 0); // Set the desired rounding mode (e.g., to zero) _controlfp(_RC_CHOP, _MCW_RC); // Perform operations with the adjusted rounding mode // Restore the original rounding mode _controlfp(originalRounding, _MCW_RC); return 0; }
Rounding Mode Decoder Ring
Rounding Mode | C Name | MSVC Name |
---|---|---|
Nearest | FE_TONEAREST | _RC_NEAR |
Zero | FE_TOWARDZERO | _RC_CHOP |
Infinity | FE_UPWARD | _RC_UP |
-Infinity | FE_DOWNWARD | _RC_DOWN |
The above is the detailed content of How Can I Efficiently Control Floating-Point Rounding Modes in C and x86 Assembly?. For more information, please follow other related articles on the PHP Chinese website!