When a float variable goes out of the float limits, what happens?
I remarked two things:
std::numeric_limits<float>::max()+(a small number)
gives:std::numeric_limits<float>::max()
.std::numeric_limits<float>::max()+(a large number
like:std::numeric_limits<float>::max()/3)
gives inf.
Why this difference? Does 1 or 2 results in an OVERFLOW and thus to an undefined behavior?
Edit: Code for testing this:
1.
float d = std::numeric_limits<float>::max();
float q = d + 100;
cout << "q: " << q << endl;
2.
float d = std::numeric_limits<float>::max();
float q = d + (d/3);
cout << "q: " << q << endl;
Formally, the behavior is undefined. On a machine with IEEE
floating point, however, overflow after rounding will result
in Inf
. The precision is limited, however, and the results
after rounding of FLT_MAX + 1
are FLT_MAX
.
You can see the same effect with values well under FLT_MAX
.
Try something like:
float f1 = 1e20; // less than FLT_MAX
float f2 = f1 + 1.0;
if ( f1 == f2 ) ...
The if
will evaluate to true
, at least with IEEE arithmetic.
(There do exist, or at least have existed, machines where
float
has enough precision for the if
to evaluate to
false
, but they aren't very common today.)
It depends on what you are doing. If the float "overflow" comes in an expression which is directly returned, i.e.
return std::numeric_limits::max() + std::numeric_limits::max();
the operation might not result in an overflow. I cite from the C standard [ISO/IEC 9899:2011]:
The return statement is not an assignment. The overlap restriction of subclause 6.5.16.1 does not apply to the case of function return. The representation of floating-point values may have wider range or precision than implied by the type; a cast may be used to remove this extra range and precision.
See here for more details.