首页 > 解决方案 > 使用整数作为小数系数而不是浮点数对于货币应用来说是一个好主意吗?

问题描述

我的应用程序需要小数乘以货币值。

例如,$65.50 × 0.55 hours = $36.025(四舍五入为$36.03)。

我知道float 不应该用来表示 money,所以我将我所有的货币价值存储为美分。$65.50上式中存储为6550(整数)。

对于小数系数,我的问题是它0.55没有 32 位浮点表示。在上面的用例中,我的应用程序需要准确计算的特定值的示例也是0.55 hours == 33 minutes如此。0.55的浮点表示0.550000012是不够的,因为用户不会明白附加值是0.000000012从哪里来的。我不能简单地调用舍入函数,0.550000012因为它会舍入到整数。

乘法解决方案

为了解决这个问题,我的第一个想法是将所有数量存储为整数并乘以 × 1000。因此0.55用户输入的内容在存储时将变为550(整数)。所有计算都将在没有浮点数的情况下进行,然后在将结果呈现给用户时简单地除以 1000(整数除法,而不是浮点数)。

编辑:

我应该澄清一下,这不是特定时间的。它适用于通用数量,例如1.256 pounds of flour1 sofa0.25 hours(想想发票)。

我在这里尝试复制的是 Postgresextra_float_digits = 0功能的更精确版本,如果用户输入0.55(float32),数据库存储0.550000012但当查询结果返回时0.55,这似乎正是用户键入的内容。

我愿意将此应用程序的精度限制在小数点后 3 位(这是商业问题,而不是科学),所以这就是让我考虑这种× 1000方法的原因。

我正在使用 Go 编程语言,但我对通用的跨语言解决方案感兴趣。

标签: gomathfloating-pointintegercurrency

解决方案


存储结果的另一种解决方案是使用值的有理形式。你可以用两个相等的整数值来解释这个数字p/q,使得两者p都是q整数。因此,您可以对数字有更高的精度,并以两个整数的格式对有理数进行一些数学运算。


推荐阅读