The most common storage for floating-point values in programming languages – IEEE singles and doubles – does not have exact representations for most decimal fractions.
The reason is that they store values in binary floating-point format, rather than decimal floating-point format. The only fractional values which can be represented exactly are those which are sums of negative powers of two. Numbers like:
- 0.5 (2^-1)
- 0.125 (2^-3)
- 0.625 (2^-1 + 2^-3)
Etc.
What you are seeing is the fact that representations of numbers like 0.96 are not exactly representable, because they are not expressible as a sum of negative powers of two. Thus, when printed out with full precision as a decimal fraction, they won’t match the original value.