All floating point numbers cannot be stored as its exact value, as the continuous space of the floating point number domain is mapped into a discrete levels. For example the floating point number can be stored in the IEEE754 single precision format. It stores the floating number in three parts in 32 bits of memory. Assume that [a, b]
are the two closest floating point numbers that can be represented exactly with IEEE754 format, but we will have infinite number of floating point numbers in between a
and b
, in that case these numbers will be approximated with either a
or b
. This induces the imprecision you are experiencing.
The number is stored in normalized format, although some very small number can be stored in unnormalized format. Just have a look at the documents.
For example in your case 56.8 IEEE754 single point precision representation will be as follows:
- sign: 0 (1 bit)
- biased exponent: 10000100 (8 bits)
- mantissa: 11000110011001100110011 (23 bits)
Now, if you convert back this number into decimal then you get
- sign is 0 ie the value is positive
- 10000100 = 132 bias amount 127 therefore exponent = 132 - 127 = 5
- mantissa with hidden bit 1.11000110011001100110011
- after adjusting decimal point with exponent (move 5 places right): 111000.110011001100110011
- The integer part : 111000 = 2^5 + 2^4 + 2^3 = 56
- The fraction part : .110011001100110011 = 2^-1 + 2^-2 + 2^-5 + 2^-6 + 2^-9 + 2^-10 + 2^-13 + 2^-14 + 2^-17 + 2^-18 = 0.799999237
Therefore when you retrieve the value from the IEEE754 single precision format it becomes: 56.799999237 where you have stored 56.8
You can play with IEEE754 representation here: http://www.h-schmidt.net/FloatConverter/IEEE754.html