Reputation: 3293
If the size of a float
is 4 bytes then shouldn't it be able to hold digits from 8,388,607
to -8,388,608
or somewhere around there because I probably calculated it wrong.
Why does f
display the extra 15
because the value of f
(0.1) is still between 8,388,607
to -8,388,608
right?
int main(int argc, const char * argv[])
{
@autoreleasepool {
float f = .1;
printf("%lu", sizeof(float));
printf("%.10f", f);
}
return 0;
}
2012-08-28 20:53:38.537 prog[841:403] 4
2012-08-28 20:53:38.539 prog[841:403] 0.1000000015
Upvotes: 1
Views: 669
Reputation: 881663
The values -8,388,608 ... 8,388,607
lead me to believe that you think floats use two's complement, which they don't. In any case, the range you have indicates 24 bits, not the 32 that you'd get from four bytes.
Floats in C use IEEE754 representation, which basically has three parts:
You basically get a certain amount of precision (such as 7 decimal digits) and the exponent dictates whether you use those for a number like 0.000000001234567 or 123456700000.
The reason you get those extra digits at the end of your 0.1
is because that number cannot be represented exactly in IEEE754. See this answer for a treatise explaining why that is the case.
Numbers are only representable exactly if they can be built by adding inverse powers of two (like 1/2
, 1/16
, 1/65536
and so on) within the number of bits of precision (ie, number of bits in the fraction), subject to scaling.
So, for example, a number like 0.5
is okay since it's 1/2
. Similarly 0.8125
is okay since that can be built from 1/2
, 1/4
and 1/16
.
There is no way (at least within 23 bits of precision) that you can build 0.1
from inverse powers of two, so it gives you the nearest match.
Upvotes: 2