⚡重温一下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 ÷

完结

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

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

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

相关推荐
BillKu28 分钟前
Vue3应用执行流程详解
前端·javascript·vue.js
欧阳天风38 分钟前
链表运用到响应式中
javascript·数据结构·链表
Codebee43 分钟前
OneCode 移动套件多平台适配详细报告
前端·人工智能
你知唔知咩系timing啊1 小时前
🎙️ 站在巨人肩膀上:基于 SenseVoice.cpp 的前端语音识别实践
前端
一位搞嵌入式的 genius1 小时前
前端开发核心技术与工具全解析:从构建工具到实时通信
前端·笔记
littleplayer1 小时前
Redux 中›ABC三个页面是如何通信的?
前端
安卓开发者1 小时前
鸿蒙NEXT的Web组件网络安全与隐私保护实践
前端·web安全·harmonyos
程序员NEO1 小时前
3分钟搞定Vue组件库
前端
程序员NEO1 小时前
WebStorm代码一键美化
前端
前端农民工ws1 小时前
Vue 框架的 markdown 渲染组件,针对 AI 的 markdown 流式传输场景
前端·javascript·vue.js·ai