【问题标题】:Dealing with prices and rounding in Javascript [closed]用Javascript处理价格和四舍五入[关闭]
【发布时间】:2019-02-27 10:57:53
【问题描述】:

所以,众所周知,0.1 + 0.2 等价于0.30000000000000004

我有一个应用程序,将在销售点用于收款,我不想处理浮点运算的噩梦。在我看来,我的选择是

a) 使用整数并将价格处理为美分/便士,在那里进行数学运算,然后除以 100 得到以美元/英镑为单位的成本

b) 使用 Decimal 库对数字进行准确的数学运算

我正在使用 react.js 和 webpack。有生产经验的大神可以给点建议吗?我倾向于选项a。

【问题讨论】:

  • 是的。将所有价格存储为美分金额。 (顺便说一句,我确实编写了一个会计应用程序,并在从数据库加载的浮点数上简单地使用了toFixed(2);到目前为止没有问题)

标签: javascript floating-point decimal


【解决方案1】:

将所有货币运算(以及任何具有固定小数位数的运算)作为整数运算并将该值转换为小数以进行显示是一种既定惯例。仅当准确性至关重要且小数位数因数字而异时才使用十进制库。

【讨论】:

  • "将所有货币运算作为整数运算进行是一种既定惯例" 是吗?我当然见过这种用法,但我不会称其为 convention - 它只是您可以做的便宜的事情,以避免作为一个整体的浮点运算,不一定与货币绑定。我认为普遍接受的变体是使用专用类型来赚钱。也就是说,如果您想与它们打交道 - 如果您只需要相当简单的计算(例如,计算所选项目的总数),那么您可以使用整数。
  • dedicated type for money -> 那会有什么不同呢?如果我曾经使用多种货币,我会使用一个包含整数值、货币代码和转换因子的类,以将不是 100 美分换算为单位的货币返回到美元/英镑/欧元等。
  • 我会用图书馆来赚钱,让它来处理这个问题。如果我必须实现自己的,我会避免使用原始类型来表示钱,并选择像 BigDecimal 这样的东西来保存数据。因为一旦你用钱进行了非平凡的操作,你就会遇到很多问题。就像汇率一样——moneyAmount * exchangeRate 迟早会给你错误的结果。如果您进行双重转换(从货币 A -> 到基础 -> 到货币 B),您将获得两次错误转换的机会。我见过这个。如果你做 A->B->A 或 A->B->C,你也可以获得四级跳
  • 您可以开始将数字相乘以避免任何形式的浮点运算,但随后您会开始失去大值的精度 - 去除小数并允许更多有效数字用于汇率,总共可能会运行 8 个订单幅度减少MAX_SAFE_INTEGER。这真的开始限制你。您仍然可以在那里安装约 9 亿,但这可能还不够,具体取决于您的需要。我们甚至还没有讨论过显示格式 - toLocaleString() 有效,但是当您拥有更多的文化和用户时,您会发现您想要更复杂的东西。
  • 至少,你想知道这个数字的货币是什么。如果您有不同的项目,您可能需要显示100 USD200 CAD 旁边、300 CNY 旁边和400 EUR。如果您只持有该金额,则必须想办法找出500 的货币单位。但拥有这些货币也可以让您更有效地求和,即使您只是不允许100 USD + 200 CAD,因为货币不同。如果你允许它,你开始转换回到第一点。所以你明白为什么“只乘并使用整数”是一个不好的标准。同样,除非是琐碎的事情。
猜你喜欢
  • 2020-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多