Материал для канала Мы ж программист

Рано или поздно каждый программист сталкивается с интересным нюансом при операциях с дробями. И для многих это становится открытием. Как думаете, каким будет результат сложения 0,1 и 0,2? Конечно же 0,3! Да, но… нет. 🤷‍♂️

Для унификации хранения и обработки чисел с плавающей точкой разработан международный стандарт IEEE 754. Из-за использования двоичного исчисления и экспоненциальной записи дробей некоторые десятичные числа могут претерпеть визуально незначительные, но в реальности критичные изменения. Во многих языках программирования, сравнив 0.1 + 0.2 и 0.3, вы получите false. Потому что 0.1 + 0.2 == 0.30000000000000004 🙃

Вот тут можно почитать подробнее про представление чисел. А вот тут найти в списке пример на своем языке программирования. Вот еще отдельная статья про Python.

Что же делать?

Основных подходов несколько:

  • Работать с целыми числами. Это особенно актуально для финансовых расчетов: проводить вычисления в целых “копейках”, а дробные “рубли” использовать только для отображения.
  • Использовать фиксированное количество знаков после запятой при сравнении (например, toFixed в JavaScript)
  • Использовать специальные дополнительные библиотеки
  • Сравнивать числа с учетом погрешности (что-то типа abs(дробь1 - дробь2) < допустимая_погрешность)

Кстати, в Java 1 равно 1, но 128 может быть не равно 128. Но это уже другая история.