Проблема потери точности при суммировании дробных чисел

Число 0.1 не представимо точно в двоичном double. Каждое сложение округляется, поэтому десять прибавлений могут дать значение чуть меньше единицы.

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

Что ответить на собеседовании

Число 0.1 не представимо точно в двоичном double. Каждое сложение округляется, поэтому десять прибавлений могут дать значение чуть меньше единицы.

Подробный разбор

Ответ с пояснениями

Условие

Найдите и объясните, почему при накоплении небольших дробных значений возникает ошибка округления.

double total = 0d;
for (var i = 0; i < 10; i++) {
    total += 0.1d;
}

Ответ

Число 0.1 не представимо точно в двоичном double. Каждое сложение округляется, поэтому десять прибавлений могут дать значение чуть меньше единицы.

Несмотря на пометку javascript, фрагмент написан на C#: синтаксис double и суффикс d не относятся к JavaScript. Типичный результат накопления — 0.9999999999999999. Это свойство конечной двоичной точности, а не ошибка цикла.

Для десятичных денежных расчётов используйте decimal total = 0m; и total += 0.1m;: данный пример даст ровно 1.0m. Для научных вычислений double обычно подходит, но сравнение выполняют с обоснованной абсолютной/относительной погрешностью. decimal тоже имеет конечную точность и не представляет точно любую дробь.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее