I've come across a surprising oddity with floating point reciprocals that only seems to occur sometimes.
Why is it that, at unexpectable times, given two floats,
float a = ..., b = ...;
testing their equivalence at one time shows they're equal,
cout << (a == b ? "T" : "F") << endl; // prints T
yet, when adjusting the same line to test the equality of the reciprocals, and running the program no differently, they are suddenly not equal:
cout << (1/a == 1/b ? "T" : "F") << endl; // prints F
Here, a
and b
are not NaN
, they're neither -INF
nor +INF
, and they're also not 0
(they're typically in the 3000 range with decimal values). I also noticed that, when compiling and running with both cout
expressions somehow they then both print T
.
Why would this be the case? I am very familiar with floating point numbers and related precision issues, but I would expect an operation on the same value to generate the same result. Or can division at times be a guesstimation/approximation instruction on certain CPUs?
Any clarification would be very appreciated.
EDIT:
As a side note, since I am starting to think this is something my compiler is doing, I am using MinGW32 GCC version 4.8.1. For targeting C++14 I'm using the flag -std=c++1y
, as this version doesn't seem to support the -std=c++14
flag.
EDIT
Could this be a compiler error? I've determined that this is an issue in the GCC 4.8.1 compiler that occurs only when compiling with optimizations (-O2
or -O3
).