1

If I test the following code, i get some strange results. I know there's a problem with doubles, since 2.1 is not 2.1 in IEEE-754. But shouldn't these be all equally wrong? The first three give 4.2, the last one 4.200000000000001

public static void main(String[] args) 
{
  double[] arr1 = {0.2, 0.2, 0.2, 0.5, 0.5, 0.5, 2.1};
  double[] arr2 = {0.5, 0.5, 0.5, 0.2, 0.2, 0.2, 2.1};
  double[] arr3 = {2.1, 0.5, 0.5, 0.5, 0.2, 0.2, 0.2};
  double[] arr4 = {2.1, 0.2, 0.2, 0.2, 0.5, 0.5, 0.5};

  System.out.println(sumarray(arr1, 0, arr1.length-1));
  System.out.println(sumarray(arr2, 0, arr2.length-1));
  System.out.println(sumarray(arr3, 0, arr3.length-1));
  System.out.println(sumarray(arr4, 0, arr4.length-1));
}

public static double sumarray(double[] arr, int p, int r) {
  double sum=arr[p];
  for (int k=p+1; k<=r; k++) {
    sum = sum + arr[k];
  }
  return sum;
}
Alexander van Oostenrijk
  • 4,644
  • 3
  • 23
  • 37
  • "*But shouldn't these be all equally wrong?*" - If they were, we could just subtract the "wrongness" and we were accurate again, wouldn't we? – Turing85 Dec 28 '19 at 12:12
  • *I know there's a problem with doubles*, your experiment is one of those problems... Addition may not be commutative. – Jean-Baptiste Yunès Dec 28 '19 at 12:13
  • This link might be of some help https://stackoverflow.com/questions/322749/retain-precision-with-double-in-java – Gratien Asimbahwe Dec 28 '19 at 13:04
  • Thanks, so let's say that someone has to treat some rational numbers, and do sums and comparisons with these, what would be his best choice? – Marco Villotta Dec 28 '19 at 15:31

2 Answers2

3

Just put System.out.println() inside your sum loop, and you will see the difference - errors are introduced at different steps. Sometimes they are mitigated. Sometimes they grow uncontrollably.

0.4
0.6000000000000001
1.1
1.6
2.1
4.2
RES: 4.2

1
1.5
1.7
1.9
2.1
4.2
RES: 4.2

2.6
3.1
3.6
3.8000000000000003
4
4.2
RES: 4.2

2.3000000000000003
2.5000000000000004
2.7000000000000006
3.2000000000000006
3.7000000000000006
4.200000000000001
RES: 4.200000000000001
x00
  • 13,643
  • 3
  • 16
  • 40
1

Why we need to use big decimal instead of double is If we subtract two values 0.03-0.02 the output for Double : 0.009999999 BigDecimal : 0.01 Double has certain precision arbitrary.when subtracting double magnitude is so large. With BigDecimal this would not happen.

The reason you should use BigDecimal for monetary calculations is not that it can represent any number, but that it can represent all numbers that can be represented in decimal notion and that include virtually all numbers in the monetary world.

HariKishore
  • 149
  • 8