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
The values
-8,388,608 ... 8,388,607lead 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.1is 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/65536and 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.5is okay since it’s1/2. Similarly0.8125is okay since that can be built from1/2,1/4and1/16.There is no way (at least within 23 bits of precision) that you can build
0.1from inverse powers of two, so it gives you the nearest match.