Reputation: 10487
I know that some values are unable to be easily defined in floats, and are only 'approximated', making direct 'equals' comparisons frequently not work.
Can std::numeric_limits::max be stored in a float accurately, and will this code function as expected?
float myFloat = std::numeric_limits<float>::max();
//...later...
if(myFloat == std::numeric_limits<float>::max())
{
//...myFloat hasn't changed...
}
Upvotes: 4
Views: 3052
Reputation: 171263
For a given (non-NaN) float
variable, f
, it is guaranteed that f == f
is always true. Since myFloat
gets set to some float
value, of course it will compare equal to that same value.
You are apparently thinking of cases such as:
float f1 = 0.1;
float f2 = 1.0/10;
assert( f1 == f2 );
which might fail, but this will not fail:
float f1 = 0.1;
float f2 = 0.1;
assert( f1 == f2 );
Although the value stored in the variables may not be exactly equal to 0.1
but may have a different value instead, you will get the same value for both variables, and so they will compare equal.
Whatever value numeric_limits<float>::max()
happens to return, it is a fixed value that will compare equal to itself.
Upvotes: 5
Reputation: 5065
Yes.
numeric limits is a class template and max is a static method:
template <class T> class numeric_limits {
public:
...
static T max() throw(); //constexpr if using C++11
...
};
So for type float you will actually be using std::numeric_limits<float>::max()
and simply comparing two floats of equal value (so long as you have not operated on myFloat prior to the comparison). The value from max() is going to be a consistent float for your platform and will have an equivalent binary representation to itself.
The main trouble you would have is trying to serialize and deserialize across platforms with a different floating point binary representation. So if you were to try and serialize your myFloat variable and on some other machine you try to compare the result of the deserialized value directly to numeric_limits::max():
if( myFloat == std::numeric_limits<float>::max() )
The result may no longer hold true. You would then need to encode your concept of "MAX" in your binary representation and interpret it explicitly how you want.
Upvotes: 4
Reputation: 111856
Yes, but
myFloat += someSmallFloat;
may not change the value of myFloat
.
If you'd like to understand more, there's a great tutorial on floating point representations called What Every Computer Scientist Should Know About Floating-Point Arithmetic.
Upvotes: 3