Почему тип double не подходит для точных финансовых расчётов?

«Почему тип double не подходит для точных финансовых расчётов?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Тип doublefloat) реализует арифметику с плавающей запятой согласно стандарту IEEE 754, что приводит к погрешностям округления при работе с десятичными дробями. Это делает его непригодным для точных вычислений, таких как финансовые операции.

Проблема на примере:

double a = 0.1;
double b = 0.2;
double sum = a + b;
System.out.println(sum); // 0.30000000000000004
System.out.println(sum == 0.3); // false!

Десятичные дроби (как 0.1) часто не имеют точного двоичного представления, что вызывает накопление ошибок.

Решение:

  1. BigDecimal (основной выбор)

    • Хранит число как строку и выполняет вычисления с заданной точностью (MathContext).
      BigDecimal a = new BigDecimal("0.1"); // Важно: использовать строковый конструктор!
      BigDecimal b = new BigDecimal("0.2");
      BigDecimal sum = a.add(b);
      System.out.println(sum.equals(new BigDecimal("0.3"))); // true
  2. Целочисленное хранение в минимальных единицах

    • Хранить сумму в копейках, центах и т.д. в типе long или BigInteger.
      long priceInCents = 199; // 1.99 USD

Вывод: Для любых расчётов, где важна точность (деньги, проценты, научные измерения), всегда используйте BigDecimal.