js 浮点小数精度问题

问题的出现

存储

计算机不可能存储无限长二进制数,因此必然发生截取。

0.2.toString(2)
// '0.001100110011001100110011001100110011001100110011001101'

查看存储精度

0.2.toPrecision(100)
// '0.2000000000000000111022302462515654042363166809082031250000000000000000000000000000000000000000000000'
// 由于存储时,截取末尾发生了进位,则实际存储值会偏大;反之未进位,则存储值会偏小。

运算

存储不准确,有些偏大有些偏小
在这基础上的运算也可能会不准确

0.2 + 0.3 == 0.5
// 一个偏大一个偏小 导致结果反而是准确的

显示

因为存储的不准确,显示为了保证也写入的逻辑一致,做了近似处理

这导致如果原本写入的数包含若干位小数,显示时被近似掉了,反倒是出现矛盾了。

let a = 0.20000000000000001110
// 0.2

但在运算时如果出现了误差放大的情况,显示又不会做近似处理
如 0.3 - 0.2

解决

解决办法 —— 第三方库

BigNumber.js:
BigNumber.js是一个用于处理任意精度的十进制数的JavaScript库。它提供了高精度的数学运算和格式化功能,可以避免JavaScript中浮点数运算带来的精度问题。

Decimal.js:
Decimal.js是另一个用于处理任意精度的十进制数的JavaScript库。它提供了高精度的数学运算和格式化功能,支持四舍五入、舍入和截断等操作。

Math.js:
Math.js是一个功能强大的数学库,除了提供了常规的数学函数和运算外,它还支持任意精度的计算。通过设置precision选项,可以控制计算的精度。

Fraction.js:
Fraction.js是一个用于处理分数的JavaScript库。它提供了分数的创建、运算和格式化功能,可以避免浮点数运算带来的精度问题。

你可能感兴趣的:(#,JavaScript,javascript,开发语言,ecmascript)