This question already has an answer here:
-
Is floating point math broken?
28 answers
In my program I have one array with 25 double values 0.04
When I try to sum these values in a loop I get following results:
0.0 + 0.04 = 0.04
0.04 + 0.04 = 0.08
0.08 + 0.04 = 0.12
0.12 + 0.04 = 0.16
0.16 + 0.04 = 0.2
0.2 + 0.04 = 0.24000000000000002
0.24000000000000002 + 0.04 = 0.28
0.28 + 0.04 = 0.32
0.32 + 0.04 = 0.36
0.36 + 0.04 = 0.39999999999999997
0.39999999999999997 + 0.04 = 0.43999999999999995
0.43999999999999995 + 0.04 = 0.4799999999999999
0.4799999999999999 + 0.04 = 0.5199999999999999
0.5199999999999999 + 0.04 = 0.5599999999999999
0.5599999999999999 + 0.04 = 0.6
0.6 + 0.04 = 0.64
0.64 + 0.04 = 0.68
0.68 + 0.04 = 0.7200000000000001
0.7200000000000001 + 0.04 = 0.7600000000000001
0.7600000000000001 + 0.04 = 0.8000000000000002
0.8000000000000002 + 0.04 = 0.8400000000000002
0.8400000000000002 + 0.04 = 0.8800000000000002
0.8800000000000002 + 0.04 = 0.9200000000000003
0.9200000000000003 + 0.04 = 0.9600000000000003
Why on earth could that happen?!
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.
See also \"What Every Computer Scientist Should Know About Floating Point\"
Other answers mentioned why, but not how to avoid it.
There are several solutions:
- Scaling: if all your numbers are multiples of 0.01 (for instance), multiply everything by 100 and use integer arithmetic (which is exact).
- Numeric type: if your language has a numeric type (like a
numeric
type in SQL), you can use it.
- Arbitrary precision rationals: use a bignum library like GMP, which allows you to represent these numbers as the ratio of two integers.
- Decimal floating point: if you have a decimal floating point like the one in IEEE-754r, you can use it.
You may wish to check out the java BigDecimal class as an alternative to floats and doubles.