/

如何修复 JavaScript 中的小数运算问题

如何修复 JavaScript 中的小数运算问题

了解如何修复 JavaScript 中的小数运算问题

如果你在 JavaScript 中尝试对两个小数进行求和,你可能会有一个惊喜。

0.1 + 0.1 是,如你所预期的,0.2

但是有时候你会得到一些意外的结果。

比如 0.1 + 0.2

结果并不是如你预期的 0.3,而是 0.30000000000000004

或者 1.4 - 1,结果是 0.3999999999999999

如何修复 JavaScript 中的小数运算问题

我确定你的问题是:为什么会这样?

首先,这不仅仅是 JavaScript 的问题,对于每一种编程语言都是一样的。

原因是计算机将数据存储为二进制的 01

任何一个值都可以表示为二进制数字系统中的一个 2 的幂。

1 可以表示为 1 * 2^0

10 可以表示为 1 * 2^1 + 0 * 2^0

并不是每个十进制数字都能够完美地在这个二进制格式中表示,因为一些数字在二进制中是重复的数字。尝试将 0.1 从十进制转换为二进制。

简而言之,我们需要无限精度来表示 0.1,虽然计算机可以很好地近似,但当我们进行计算时,我们会失去一些数据,因为我们需要在某个地方“截断”,这就导致了你在上面看到的那些意外的结果。

你可以使用像 decimal.js、bignumber.js 或 big.js 这样的库。

你也可以使用这样的“技巧”。

你决定在小数点后面截断两个位置,例如,将数字乘以 100 来去除小数部分。

然后在求和后除以 100:

1
2
3
0.1 + 0.2 //0.30000000000000004

(0.1.toFixed(2) * 100 + 0.2.toFixed(2) * 100) / 100 //0.3

使用 10000 而不是 100 来保留 4 位小数。

更抽象化的方式:

1
2
3
4
5
6
const sum = (a, b, positions) => {
const factor = Math.pow(10, positions)
return (a.toFixed(positions) * factor + b.toFixed(positions) * factor) / factor
}

sum(0.1, 0.2, 4) //0.3

tags: [“JavaScript”, “decimal arithmetic”, “binary representation”]