Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как считать деньги в Java

Короткий ответ

double хранит дробные числа приблизительно, поэтому для денег используют BigDecimal:

void main() {
    IO.println(0.1 + 0.2);
    IO.println(new BigDecimal("0.10").add(new BigDecimal("0.20")));
}

Результат:

0.30000000000000004
0.30

Арифметика

Операторы + и * с BigDecimal не работают — нужны методы. Каждый метод возвращает новое число:

void main() {
    var price = new BigDecimal("19.99");
    var quantity = BigDecimal.valueOf(3);
    var discount = new BigDecimal("5.00");
 
    var total = price.multiply(quantity).subtract(discount);
    IO.println(total);
}

Результат:

54.97

Налог с округлением

После умножения на процент знаков становится больше — округлите до копеек:

void main() {
    var net = new BigDecimal("49.99");
    var vat = net.multiply(new BigDecimal("0.19"));
 
    IO.println(vat);
    IO.println(vat.setScale(2, RoundingMode.HALF_UP));
}

Результат:

9.4981
9.50

Деление

При делении укажите масштаб и правило округления, иначе бесконечная дробь вызовет исключение:

void main() {
    var bill = new BigDecimal("100.00");
    var share = bill.divide(BigDecimal.valueOf(3), 2, RoundingMode.HALF_UP);
 
    IO.println(share);
}

Результат:

33.33

Сравнение

equals() учитывает количество знаков после запятой, а compareTo() — только значение:

void main() {
    var a = new BigDecimal("2.0");
    var b = new BigDecimal("2.00");
 
    IO.println(a.equals(b));
    IO.println(a.compareTo(b) == 0);
}

Результат:

false
true

Частая ошибка

Создавать BigDecimal из double. Неточность double переходит в BigDecimal целиком:

void main() {
    IO.println(new BigDecimal(0.1));
    IO.println(new BigDecimal("0.1"));
    IO.println(BigDecimal.valueOf(0.1));
}

Результат:

0.1000000000000000055511151231257827021181583404541015625
0.1
0.1

Создавайте из строки или через BigDecimal.valueOf().

Функции из этого ответа

  • BigDecimal — Точное десятичное число — для денег и расчётов, где недопустимы ошибки округления double.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.