Как не получить недостачу в кассе при программировании
У цен в разработке есть проблема — копейки. Те самые числа после запятой.
1. При передаче через API или json число со знаком может превратиться в целочисленное (int), так и в дробное (float). 1.00 -> 1. Из-за этого при сравнении типов дальше в коде может вылезти ошибка.
2. При вычислениях с числами накапливаются погрешности. Если сложить в php 0.1 + 0.2, то получится, не 0.3, а 0.30000000000000004
Казалось бы какая разница. Но в интернет-магазине числа могут умножаться, суммироваться, применяться скидки — рано или поздно погрешность округлиться не в ту сторону. Не сойдется копейка, а с ней вся бухглатерия. А еще есть крипта, где может быть сильно больше знаков после запятой.
Разобрался почему так
Есть стандарт IEEE 754. У него есть плюс, он офигенно быстро работает. И подходит для большинства задач, кроме денежных. Если бы не этот стандарт, то все компьютеры бы работали медленнее. Это всё особенности хранения памяти.
Есть, кстати, байка про ракету в 91 году, которая накопила погрешности, отклонилась от курса и не смогла защитить от вражеской ракеты. Мы с вами не ракеты строим (я надеюсь), но бухглатерия, которая будет 3 дня искать ошибку — ощутимая потеря.
Что делать?
1. Хранить всё в целых числах 1234,10 -> 123410 и при отображении отделять копейки. Или в строках.
2. Все вычисления делать в случае с пхп, через библиотеку bcmath. В случае с другими языками использовать BigInt. В Java он, например из коробки.
В 1С, кстати, такой проблемы нет. Возможно поэтому она вечно тормозит :)
——————————
Это может быть хорошим вопросом при собеседовании или отборе подрядчика. Так как любой нормальный миддл — знает ответ на вопрос, он много раз разжевывался на Хабре. А тот кто только закончил курсы и притворяется опытным, в спешке «сеньор за 3 месяца» про такие детали забудет.
Post #487
600

- ❤ 5
- ⚡ 2
- 🔥 1