前端中Javascript精度问题理解

1.Javascript 精度问题的产生

精度问题其实是一个"共性"问题
日常生活中的"十进制"

  1. 精度问题的产生:使用"十进制除法"无法除尽的时候就会产生精度问题,例如1/3无法在十进制中除尽。
  2. 精度问题的描述:那我们表达这种无法除尽的问题是用0.3(3循环)来描述。

计算机中的"二级制"

  1. 精度问题的产生:二进制中在无法乘尽的时候会产生精度问题。

  2. 精度问题的描述 :计算机由于存储空间限制,无法像十进制那样使用循环表示,因此只能有限的描述数字精度,目前描述方式主要采用四种"浮点型":单精度32位,延伸单精度43位、双精度64位、延伸双精度90位。尽管储存位数很多,但毕竟是有限的。这种 "有限性 " 就导致了java、c++、javascript等计算机语言中的"精度丢失"。

二进制转化:

二进制整数:除法。"二进制"很少存在无法除尽的时候,因为除以二余数要不是0、1,而我们需要的就是0、1。

二进制小数:乘法。经常存在无法乘进的时候,因为小数位乘以2后,数值截整,剩下小数继续乘以2。0

2.Javascript中的精度存储原因

js采用的是浮点运算标准,而IEEE规定的浮点数值运算标准主要有四种方式来保证精度:单精度(32位)、延伸单精度(43位)、双精度(64位)、延伸双精度(80位)。其中js采用的是双精度64位,其中小数部分最多支持53位的存储,如果超出会被截断。

3.工作中哪些场景可能会遇到js精度问题

场景1小数循环引起的精度问题 :(小数运算)

case1:比如我们在控制台输入:1.15 * 100 ,那么展示的不是115而是114.999999999999。如果我们向下取整Math.floor,再除以100的话,那么值就变成了1.14,少了0.01。在下付款单的时候,我们经常会遇到这样会那样的乘法除法运算,很可能因为类似情况出现精度丢失问题。

case2:

js 复制代码
0.1 + 0.2 != 0.3 // True
因为先把0.1、0.2的二进制分别算出来,结果不等于0.3的二进制表示。

场景2大数过大引起的精度问题 - 前后端大数据值id传递:前端获取到的roomid10976458979374928, 后端返回的:roomid10976458979374929。并且前端在network中看到的都是10976458979374928

这个时候需要先判断是不是缓存的问题,排除缓存问题后,可以考虑是否为精度问题。

那为什么java中可以正常存储呢?因为js中Number类型的数字范围是:-2^53 + 1 到 2^53 - 1,而java中的取值范围是-2^63 + 1 到 2^63 - 1,比js要大很多,所以在java中没有出现这个问题。

场景3:toFixed(n)API截取小数位不准确。 问题原因:toFix不是按照银行家的四舍五入规则进行截取的, 而是有自己的一套四舍六入五考虑(五后任有数就进一,五后无数字看前面,五前为奇数应舍去,五前为偶要进一),那么当我们截取两位的时候,并且第二位小数小于5,第三位小数大于5,那么就会导致不会向前进一位。此外返回的类型是字符串类型也需要额外转换。

js 复制代码
0.615.toFixed(2) // 返回字符串'0.61'而不是'0.62'
1.35.toFixed(1) // '1.4' 正确
1.335.toFixed(2) // '1.33'  错误
1.3335.toFixed(3) // '1.333' 错误
1.33335.toFixed(4) // '1.3334' 正确
1.333335.toFixed(5)  // '1.33333' 错误
1.3333335.toFixed(6) // '1.333333' 错误

怎么判断一个Number类型数字是否在允许的精度范围内呢?

在js中Number类型的数字范围是:-2^53 + 1 到 2^53 - 1 ES6中引入了Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER这两个常量来表示上下限范围。 Number.isSafeInteger()用来判断一个整数是否落在这个范围之内。

4.怎么解决或者避免js精度问题

场景1:小数前端运算导致的精度丢失

场景2:小数位截取toFixed(2)-API导致的精度丢失

场景3:大数前端运算导致的精度丢失

场景4:后端id传大数,前端回显精度丢失

如果是存储位置不够导致的,可以通过第三方库decimal.js使用

相关推荐
李姆斯21 分钟前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜1 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司1 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
江华森2 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http
IT_陈寒2 小时前
Redis的KEYS命令把我搞崩溃了,改用SCAN才活过来
前端·人工智能·后端
Jackson__3 小时前
为什么 Agent 越聊越慢?聊聊 Context(上下文)管理
前端·agent·ai编程
KaMeidebaby3 小时前
卡梅德生物技术快报|抗体合成:多肽抗体合成工程化方案:Nsp2 保守肽多抗制备与多维度验证
前端·网络·数据库·人工智能·算法
青禾网络3 小时前
前端做音画匹配这件事,我从"随机塞"到"AI 自动对齐"
前端·github
2601_963771374 小时前
Hardening Enterprise WordPress Sites Against REST API Leaks and Bad Headers
前端·windows·word·php
蓝银草同学4 小时前
Stream 实战:博客列表排序、过滤与分页(AI 辅助学习 Java 8)
java·前端·后端