问题
If I try this
float f = (float)numeric_limits<double>::infinity();
Or indeed, try to cast anything bigger than float max down to a float, am I guaranteed to end up with infinity?
It works on GCC, but is it a standard though?
回答1:
float f = (float)numeric_limits<double>::infinity();
This is guaranteed to set f
to infinity if your compilation platform offers IEEE 754 arithmetic for floating-point computations (it usually does).
Or indeed, try to cast anything bigger than float max down to a float, am I guaranteed to end up with infinity?
No. In the default IEEE 754 round-to-nearest mode, a few double
values above the maximum finite float
(that is, FLT_MAX
) convert to FLT_MAX
. The exact limit is the number midway between FLT_MAX
(0x1.fffffep127
in C99 hexadecimal representation) and the next float
number that could be represented if the exponent in the single-precision format had a larger range, 0x2.0p127
. The limit is thus 0x1.ffffffp127
or approximately 3.4028235677973366e+38 in decimal.
回答2:
From the C++11 standard, §4.8.1:
A prvalue of floating point type can be converted to a prvalue of another floating point type. If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation. If the source value is between two adjacent destination values, the result of the conversion is an implementation-defined choice of either of those values. Otherwise, the behavior is undefined.
This implies that
If you cast double infinity to float, you get float infinity.
If you cast a double value, that lies between float max and infinity, to float, then you get float max or float infinity.
来源:https://stackoverflow.com/questions/17751031/downcasting-double-to-float-is-overflow-behaviour-guaranteed