Умножение Long на число с плавающей точкой в ​​некоторых случаях приводит к ошибкам - PullRequest
0 голосов
/ 31 мая 2019

См. Ниже простой код:

public static void main(String[] args) {
    Long value = 91000L;
    System.out.println(value * 0.1);
    System.out.println(value * 0.2);
    System.out.println(value * 0.3);
    System.out.println(value * 0.4);
    System.out.println(value * 0.5);
    System.out.println(value * 0.6);
    System.out.println(value * 0.7);
    System.out.println(value * 0.8);
    System.out.println(value * 0.9);
}

результат таков:

9100.0
18200.0
27300.0
36400.0
45500.0
54600.0
63699.99999999999 //incorrect!
72800.0
81900.0

1 Ответ

3 голосов
/ 31 мая 2019

Это правильный результат, потому что работа с двойными не точна, как работа с целочисленными типами.

Вот почему, если вы сравниваете два double числа, вам нужно что-то сделать. как это:

public static boolean isEqual(double one, double two) {
    return one >= two - 1E6 && one <= two + 1E6;
}

P.S. 4.2.3. Типы с плавающей точкой, форматы и значения

Если вы хотите напечатать правильное значение, вы должны использовать BigDecimal:

BigDecimal val = BigDecimal.valueOf(91000);
BigDecimal res = val.multiply(BigDecimal.valueOf(0.7));
System.out.println(res); // 63000.0

В некоторых случаях вы можете увеличить точность:

long value = 91000L;
System.out.println(value * 0.7);    // 63699.99999999999
System.out.println((value * 7) / 10);   // 63700
...