I'm reading CS:APP, and regarding casts it says that when casting from int to float, the number cannot overflow, but it may be rounded.
It seemed odd to me as I didn't know what there was to round, so I've tried it out. I thought that this would only be the case for very large integers (near INT_MAX
/INT_MIN
), but rounding happens at values around a hundred million as well. (Not sure where exactly this happens first).
Why does this happen? The range of float
far exceeds that of int
. One might say that floating point numbers cannot be represented exactly, but when converting from int
to double
there is no change in value. The advantage of double
over float
is that it has greater range and precision. But float
still has enough range to "encapsulate" integers, and precision shouldn't really matter as integers have no decimal places (well, all 0), or am I thinking wrong?
Here's some output that I got (here is the code: http://pastebin.com/K3E3A6Ni):
FLT_MAX = 340282346638528859811704183484516925440.000000
INT_MAX = 2147483647
(float)INT_MAX = 2147483648.000000
(double)INT_MAX = 2147483647.000000
INT_MIN = -2147483648
(float)INT_MIN = -2147483648.000000
====other values close to INT_MIN INT_MAX====
INT_MAX-1 = 2147483646
(float)INT_MAX-1 = 2147483648.000000
INT_MIN+1 = -2147483647
(float)INT_MIN+1 = -2147483648.000000
INT_MAX-2 = 2147483645
(float)INT_MAX-2 = 2147483648.000000
INT_MAX-10 = 2147483637
(float)INT_MAX-10 = 2147483648.000000
INT_MAX-100 = 2147483547
(float)INT_MAX-100 = 2147483520.000000
INT_MAX-1000 = 2147482647
(float)INT_MAX-1000 = 2147482624.000000
(float)1.234.567.809 = 1234567808.000000
(float)1.234.567.800 = 1234567808.000000
(float)1.000.000.005 = 1000000000.000000
(float)800.000.003 = 800000000.000000
(float)500.000.007 = 500000000.000000
(float)100.000.009 = 100000008.000000
I'm assuming that by float
you mean a 32-bit IEEE-754 binary floating point value, by double
you mean a 64-bit IEEE-754 binary floating point value, and by int
you mean a 32-bit integer.
Why does this happen? The range of float far exceeds that of int
Yes, but the precision of float
is only 7-9 decimal digits. To be more specific, the significand is only 24 bits wide... so if you're trying to store 32 bits of information in there, you're going to have problems.
but when converting from
int
todouble
there is no change in value
Sure, because a double
has a 53-bit significand - plenty of room for a 32-bit integer there!
To think of it another way, the gap between consecutive int
values is always 1... whereas the gap between consecutive float
values starts very, very small... but increases as the magnitude of the value increases. It gets to "more than 2" well before you hit the limit of int
... so you get to the stage where not every int
can be exactly represented.
To think of it another way, you can simply use the pigeon-hole principle... even ignoring NaN values, there can be at most 232 float
values, and at least one of those is not the exact value of an int
- take 0.5, for example. There are 232 int
values, therefore at least one int
value doesn't have an exact float
representation.
See more on this question at Stackoverflow