Мое приложение требует дробного количества, умноженного на денежное значение.
Например, $65.50 × 0.55 hours = $36.025
(округлено до $36.03
).
Я знаю, что числа с плавающей запятой не должны использоваться для представления денег , поэтому я храню все мои денежные значения в виде центов. $65.50
в приведенном выше уравнении сохраняется как 6550
(целое число).
Что касается дробного коэффициента, моя проблема в том, что 0.55
не имеет 32-битного представления с плавающей запятой. В приведенном выше примере использования 0.55 hours == 33 minutes
, поэтому 0.55
является примером определенного значения, которое мое приложение должно будет точно учитывать. Представление с плавающей точкой 0.550000012
недостаточно, потому что пользователь не поймет, откуда взялся дополнительный 0.000000012
. Я не могу просто вызвать функцию округления на 0.550000012
, потому что она округляется до целого числа.
Решение для умножения
Чтобы решить эту проблему, моя первая идея состояла в том, чтобы сохранить все величины в виде целых чисел и умножить на 1000. Таким образом, 0.55
, введенное пользователем, станет 550
(целое число) при сохранении. Все вычисления будут выполняться без значений с плавающей точкой, а затем просто делятся на 1000 (целочисленное деление, а не число с плавающей точкой) при представлении результата пользователю.
Я понимаю, что это навсегда ограничит меня до 3 десятичных знаков
точность. Если я решу, что 3 достаточно для жизни моего
приложение, имеет ли этот подход смысл?
Есть ли потенциальные проблемы с округлением, если бы я использовал целочисленное деление?
Есть ли название для этого процесса? РЕДАКТИРОВАТЬ: Как указано @SergGr, это арифметики с фиксированной точкой .
Есть ли лучший подход?
EDIT:
Я должен был уточнить, это не зависит от времени. Это для общих величин, таких как 1.256 pounds of flour
, 1 sofa
или 0.25 hours
(например, счета).
Здесь я пытаюсь воспроизвести более точную версию функциональности Postgres extra_float_digits = 0
, где, если пользователь вводит 0.55
(float32), база данных хранит 0.550000012
, но при запросе результата возвращает 0.55
который выглядит точно так, как набрал пользователь.
Я хочу ограничить точность этого приложения до 3 десятичных знаков (это бизнес, а не наука), так что именно это заставило меня рассмотреть подход × 1000
.
Я использую язык программирования Go, но меня интересуют универсальные межъязыковые решения.