Рано или поздно каждый программист сталкивается с интересным нюансом при операциях с дробями. И для многих это становится открытием. Как думаете, каким будет результат сложения 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. Но это уже другая история.