Reputation: 221
#include <iostream>
int main() {
int num = 2147483647;
std::cout << (int)(float)num << std::endl;
return 0;
}
./main
-2147483648
-2147483648
I know that a float to int conversion is safe, but an int to float conversion is not. I also know that real floating point cannot be expressed accurately. It seems very dangerous to see overflows even though the maximum value(except inf) of int is not exceeded.
I want to be safe when converting int to float or float to int no matter what arbitrary number comes in.
Which way is best to handle it? Also, what other exceptions should I consider?
The above question isn't clear and doesn't fit the stackoverflow question, so I'll fix it specifically.
Numbers in normal categories like 2147483647 also overflow. What range should I handle?
Upvotes: 1
Views: 1317
Reputation: 153457
I know that a float to int conversion is safe, but an int to float conversion is not.
Each conversion has issues.
(Assume 32-bit int
and 32-bit float
for discussion.)
Large int
to float
risks lost of precision as float
does not exactly encode all int
. With OP's int num = 2147483647; (float)num
, the 2147483647 was converted to 1 of 2 nearby float
. With round to the nearest rounding mode, float
: result was certainly 2147483648.0.
float
to int
truncates any fraction. Conversion from infinity and Not-a-number pose addition concerns.
float
to int
risks implementation-defined behavior when the the floating point value is not inside the -2,147,483,648.9999... 2,147,483,647.9999... range. This is the case with OP's int num = 2147483647; (int)(float)num
attempting to convert an out of range 2147483648.0 to int
. In OP's case, the value was apparently wrapped around (232 subtracted) to end with -2147483648.
Which way is best to handle it? Also, what other exceptions should I consider?
With conversion int
to float
, expect rounding for large int
.
With conversion float
to int
, expect truncation and perhaps test if value is in range.
With 2's complement integer encoding: a test to prevent out of range conversion.
#define FLT_INT_MAX_PLUS1 ((INT_MAX/2 + 1)*2.0f)
// return true when OK to convert
bool float_to_int_test(float x) {
return (x < FLT_INT_MAX_PLUS1) && (x - INT_MIN > -1.0f);
}
Other tests could be had to determine rounding or truncation.
Upvotes: 3