JavaScript 中的精确财务计算。陷阱是什么?

新手上路,请多包涵

为了创建跨平台代码,我想用 JavaScript 开发一个简单的财务应用程序。所需的计算涉及复利和相对较长的小数。我想知道在使用 JavaScript 进行此类数学运算时要避免哪些错误——如果可能的话!

原文由 james_womack 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 405
2 个回答

您可能应该将十进制值缩放 100,并以整分表示所有货币值。这是为了避免 出现浮点逻辑和算术问题。 JavaScript 中没有十进制数据类型——唯一的数字数据类型是浮点数。因此,通常建议将钱处理为 2550 美分,而不是 25.50 美元。

考虑一下在 JavaScript 中:

 var result = 1.0 + 2.0;     // (result === 3.0) returns true

但:

 var result = 0.1 + 0.2;     // (result === 0.3) returns false

表达式 0.1 + 0.2 === 0.3 返回 false ,但幸运的是浮点整数运算是精确的,因此可以通过缩放1来避免十进制表示错误。

请注意,虽然实数集是无限的,但只有有限数量的实数(准确地说是 18,437,736,874,454,810,627)可以用 JavaScript 浮点格式精确表示。因此,其他数字的表示将是实际数字2的近似值。


1 Douglas Crockford: JavaScript:好的部分:附录 A - 糟糕的部分(第 105 页)

2 David Flanagan: JavaScript:权威指南,第四版:3.1.3 浮点文字(第 31 页)

原文由 Daniel Vassallo 发布,翻译遵循 CC BY-SA 3.0 许可协议

将每个值缩放 100 就是解决方案。手动执行可能没有用,因为您可以找到可以为您执行此操作的库。我推荐 moneysafe,它提供了一个非常适合 ES6 应用程序的功能性 API:

 const { in$, $ } = require('moneysafe');
console.log(in$($(10.5) + $(.3)); // 10.8

https://github.com/ericelliott/moneysafe

适用于 Node.js 和浏览器。

原文由 François Zaninotto 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题