Improves the consistency of floating-point tests for equality and inequality by disabling optimizations that could change the precision of floating-point calculations, which is required for strict ANSI conformance. By default, the compiler uses the coprocessor's 80-bit registers to hold the intermediate results of floating-point calculations. This increases program speed and decreases program size. Because the calculation involves floating-point data types that are represented in memory by less than 80 bits, however, carrying the extra bits of precision (80 bits minus the number of bits in a smaller floating-point type) through a lengthy calculation can produce inconsistent results.
With /fp:precise on x86 processors, the compiler will perform rounding on variables of type float to the proper precision for assignments and casts and when passing parameters to a function. This rounding guarantees that the data does not retain any significance greater than the capacity of its type. A program compiled with /fp:precise can be slower and larger than one compiled without /fp:precise. /fp:precise disables intrinsics; the standard run-time library routines are used instead. For more information, see /Oi (Generate Intrinsic Functions).
The following floating-point behavior is enabled with /fp:precise:
Contractions, or replacing multiple operations with one composite operation with only a single rounding at the end, is enabled with /fp:precise.
Expression optimizations that are invalid for special values (NaN, +infinity, -infinity, +0, -0) will not be allowed. The optimizations x-x => 0, x*0 => 0, x-0 => x, x+0 => x, and 0-x => -x are all invalid for various reasons (see IEEE 754 and the C99 standard).
The compiler will properly handle comparisons involving NaN. For example, x != x evaluates to true if x is NaN and ordered comparisons involving NaN raise an exception.
Expression evaluation will follow the C99 FLT_EVAL_METHOD=2, with one exception. When programming for x86 processors, because the FPU is set to 53-bit precision, this will be considered long double precision.
Multiplication by exactly 1.0 transformed into a use of the other factor. x*y*1.0 is transformed into x*y. Similarly, x*1.0*y is transformed into x*y.
Division by exactly 1.0 is transformed into a use of the dividend. x*y/1.0 is transformed into x*y. Similarly, x/1.0*y is transformed into x*y.
Using /fp:precise with fenv_access ON disables some optimizations such as compile-time evaluations of floating point expressions. For example, if you change rounding mode with _control87, _controlfp, __control87_2, and the compiler performs a floating-point calculation, the rounding mode you specified will not be in effect unless fenv_access is ON.
/fp:precise replaces the /Op compiler option.
Creates the fastest code in the majority of cases. /fp:fast cannot be used with /fp:strict or /fp:precise, the last option specified on the command line will be used. /fp:fast and /fp:except will generate a compiler error.
Selecting /Za, /Ze (Disable Language Extensions) (ANSI compatibility) and /fp:fast may result in unexpected behavior. For example, single-precision floating-point operations may not be rounded to single precision.
Reliable floating-point exception model. Exceptions will be raised immediately after they are triggered. This option is off by default. Appending a minus sign to the option explicitly disables it.
The strictest floating-point model. /fp:strict causes fp_contract to be OFF and fenv_access to be ON. /fp:except is implied and can be disabled by explicitly specifying /fp:except-. When used with /fp:except-, /fp:strict enforces strict floating-point semantics but without respect for exceptional events.
Multiple /fp options can be specified in the same compilation.
To control floating-point behavior by function, see the float_control pragma.
Most of the floating-point optimizations related to /fp:strict, /fp:except (and its corresponding pragmas), and fp_contract pragma are machine dependent. /fp:strict and /fp:except are not compatible with /clr.
/fp:precise should address most of an application's floating-point requirements. If necessary, you can use /fp:except and /fp:strict, but there may be some decrease in performance. If performance is most important, you may want to use /fp:fast.
/fp:strict, /fp:fast, and /fp:precise are precision (correctness) modes. Only one can be in effect at a time. If /fp:strict and /fp:precise are specified, the compiler use the one that it processes last. You cannot specify both /fp:strict and /fp:fast.