⚡重温一下JS精度引发的问题了

前言

最近测试给我提了个BUG,我看到的第一感觉就是这必须是后端的锅

本着不冤枉任何一个好人的态度,我还是自己看了下页面展示、接口回参和逻辑处理部分,最后发现,nnd竟然是我的(JS精度)问题。

想着,应该有些小伙伴挺感兴趣的,索性就把笔记更新到这里吧~~~

正文开始

1,为什么JS会有精度问题

精度问题是因为计算机在存储和计算数字时,使用的是二进制形式。有些十进制数字在转换成二进制时无法精确表示,比如0.1在二进制中是无限循环小数。

因此,当在JavaScript中进行浮点数运算时,就会出现精度误差。

整数和整数相乘,通常不会出现精度问题

1.1,十进制转二进制

乘2取整法(用于小数)

js 复制代码
将0.1转为二进制的过程如下:


0.1 * 2 = 0.2,无整数部分,取0
0.2 * 2 = 0.4,无整数部分,取0
0.4 * 2 = 0.8,无整数部分,取0
0.8 * 2 = 1.6,有整数部分1,取1,剩余小数部分0.6
0.6 * 2 = 1.2,有整数部分1,取1,剩余小数部分0.2
0.2 * 2 = 0.4,无整数部分,取0
... 之后的过程会不断重复

按照这种格式表示,0.1的二进制表示为:**0.0001100110011001...** ,是一个无限循环小数

除2取余法(用于整数)

js 复制代码
将100转为二进制的过程如下:

100 / 2 = 50 余0
50 / 2 = 25 余0
25 / 2 = 12 余1
12 / 2 = 6 余0
6 / 2 = 3 余0
3 / 2 = 1 余1
1 / 2 = 0 余1

然后将所有余数倒序排列,得到数1100100,这就是100的二进制表示。

1.2,二进制转十进制

js 复制代码
将1100100转为十进制的过程如下:

1*2^6 = 64
1*2^5 = 32
0*2^4 = 0
0*2^3 = 0
1*2^2 = 4
0*2^1 = 0
0*2^0 = 0

64+32+0+0+4+0+0=100

1.3,为什么0.1+0.2 !== 0.3 但是 0.2 + 0.2 === 0.4

js 复制代码
0.1(十进制) = 0.0001100110011001(二进制)  超出计算精度,结果保留十六位小数

0.2(十进制) = 0.0011001100110011(二进制)  超出计算精度,结果保留十六位小数

0.3(十进制) = 0.0100110011001100(二进制)  超出计算精度,结果保留十六位小数

0.1+0.2这两个数在二进制表示下都存在精度误差,它们的和不等于精确的0.3,所以0.1+0.2 !== 0.3。

0.2+0.2这两个数在二进制表示下虽然也存在精度误差,但是当它们相加时,这些误差恰好抵消了,使得它们的和等于精确的0.4,所以0.2+0.2 === 0.4。(0.1 + 0.3 === 0.4也同理)

2,JS精度有问题的案例

3,解决方案

3.1,转成整数进行计算

先乘以100化为整数,再除

3.2,转成字符串然后截取

3.3,使用第三方库

Math.js 解决大数计算和精度问题

js 复制代码
math.config({ number: 'BigNumber', precision: 64 }); 

console.log(math.format(math.eval('0.1 + 0.2'))); // '0.3' 

console.log(math.format(math.eval('9007199254740991 + 2'))); // '9.007199254740993e+15'

number-precision 解决浮点数

js 复制代码
NP.plus(0.1, 0.2); // 0.3 + 

NP.minus(1.0, 0.9); // 0.1 - 

NP.times(3, 0.3); // 0.9 * 

NP.divide(0.9, 0.3); // 3 ÷

完结

这篇文章我尽力把我的笔记和想法放到这了,希望对小伙伴有帮助。

欢迎转载,但请注明来源。

最后,希望小伙伴们给我个免费的点赞,祝大家心想事成,平安喜乐。

相关推荐
时间的情敌5 小时前
Vue3 + Cesium 实战:本地上传 GLB 模型、模型上叠加 GLB、点击控制透明度
前端·vue.js·cesium
拖孩5 小时前
流量主门槛从 500 降到 100,我的小程序上线 18 小时够到了线
前端·后端·微信小程序
深蓝AI5 小时前
编码 Agent 的界面味靠提示词压不住:Impeccable 用无模型规则拦同一套模板
前端·程序员
CCIE-Yasuo6 小时前
网络安全-Javascript基础
javascript·安全·web安全
January12076 小时前
【AI方法笔记】2026-11-02:模型流式吐 JSON 时,前端会遇到四种崩法
前端·人工智能·笔记·json
asdzx677 小时前
C# 操作 PDF 元数据:从属性写入到字段提取的完整流程
前端·pdf·c#
幻境如梦丶皆为虚7 小时前
从零写一个 DSH 插件:在左侧菜单栏加一个「测试」
开发语言·javascript·ecmascript
吹什么轩7 小时前
constexpr 完全指南:从 const 的两种含义,到编译期计算的四次演进
java·前端·javascript
Bruce_Liuxiaowei7 小时前
前端校验登录态,等于没校验——一次应急广播终端高危漏洞的发现与报送
运维·前端·安全
Meta Luo7 小时前
AI 时代,Web 自动化测试该怎么做?
前端·人工智能·playwright 替代工具·无代码自动化测试工具·低代码 ui 自动化测试·web 回归测试工具