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

2022-08-30 02:40:05

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


答案 1

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

考虑一下JavaScript中的情况:

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

但:

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

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

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


1 Douglas Crockford: JavaScript: The Good Parts: Annex A - Awful Parts (第105頁)
2 David Flanagan: JavaScript: The Definitive Guide, Fourth Edition: 3.1.3 Floating-Point Literals (page 31).


答案 2

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

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

https://github.com/ericelliott/moneysafe

在 Node.js 和浏览器中都有效。