MORE INFORMATION
The following code sample illustrates this issue.
Note This code sample must be compiled on a Intel Pentium x86-based computer, and the first line of the code sample must be the command-line switch
-fp:precise or the command line switch
-fp:strict.
1 //Insert the command-line switch here.
2 #include <math.h>
3 #include <stdio.h>
4 #include <float.h>
5 int main()
6 {
7 // assume _controlfp(_PC_53, _MCW_PC);
8 double m = DBL_MAX;
9 double d0, d1, d2;
10 d0=m+m-m;
11 d1=double(m+m)-m;
12 d2=m+m;
13 d2=d2-m;
14 printf("d0=%lf\n",d0);
15 printf("d1=%lf\n",d1);
16 printf("d2=%lf\n",d2);
17 if (d1!=d2)
18 {
19 if (d1==d0)
20 printf("ERROR: explicit double rounding was not honored");
21 else
22 printf("ERROR: expected d1==d2, d1!=d2 on x86");
23 return -1;
24 }
25 printf("Passed");
26 return 0;
27 }
In line 8, the variable m is set to the largest numeric value for a double numeric type. In line 9, the variables d0, d1, and d2 are set to the double numeric type. In Visual C++, all calculations store intermediate values in the register. The register of an Intel Pentium processor is set to double precision and has a wider long-double exponent.
In line 10, the intermediate value
m+m-m is calculated in the register. Then, the intermediate value is converted to a double numeric type. Finally, the converted intermediate value is assigned to the variable d0.
In line 11, the intermediate value
m+m is calculated in the register. Then, the intermediate value should be converted to a double numeric type. However, the intermediate value is not converted because of the issue that is mentioned in the "Symptoms" section. Next, m is subtracted from the unconverted intermediate value. This subtraction creates a second intermediate value. Then, the second intermediate value is converted to a double numeric type. Finally, the second intermediate value is assigned to the variable d1.
In line 12, the intermediate value
m+m is calculated in the register. Then, the intermediate value is converted to a double numeric type. Finally, the converted intermediate value is assigned to the variable d2.
In line 13, the intermediate value
d2-m is calculated in the register. Then, the intermediate value is converted to a double numeric type. Finally, the converted intermediate value is assigned to the variable d2.
The issue that is mentioned in the "Symptoms" section causes the following conditions to be true:
- d0 is equal to d1
- d1 is not equal to d2
You expect the following conditions to be true:
- d0 is not equal to d1
- d1 is equal to d2