The procedure cos (x) == cos (x) generated in the release mode:
00DB101A call _CIcos (0DB1870h)
00DB101F fld st (0)
00DB1021 fucompp
The value is calculated once, and then cloned, then compared with itself - the result will be OK
Same thing in debug mode:
00A51405 sub esp, 8
00A51408 fld qword ptr [x]
00A5140B fstp qword ptr [esp]
00A5140E call @ ILT + 270 (_cos) (0A51113h)
00A51413 fld qword ptr [x]
00A51416 fstp qword ptr [esp]
00A51419 fstp qword ptr [ebp-0D8h]
00A5141F call @ ILT + 270 (_cos) (0A51113h)
00A51424 add esp, 8
00A51427 fld qword ptr [ebp-0D8h]
00A5142D fucompp
Strange things are happening now.
1. X is uploaded to fstack (X, 0)
2. X is stored on a regular stack (truncation)
3. Cosine is calculated, the result on the fleet stack
4. boot X again
5. X is stored on a regular stack (truncation, since now we are "symmetrical")
6. The result of the 1st cosine that was on the stack is stored in memory, now another truncation occurs for the 1st value
7. Cosine is calculated, the 2nd result, if on a float-stack, but this value was truncated only once
8. The first value is uploaded to fstack, but this value has been truncated twice (once before calculating the cosine, once after)
9. These 2 values are compared - we get rounding errors.
source share