前端中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传递:前端获取到的roomid:10976458979374928, 后端返回的:roomid:10976458979374929。并且前端在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使用

相关推荐
原则猫8 小时前
UDP 到底怎么实现可靠的
前端
Java后端的Ai之路8 小时前
14、ReactJS - 路由(Router)
前端·react.js·状态模式
裕晟资质规划10 小时前
三类涉密资质延续时限差异分析:军工60日与集成印制3个月的边界
java·服务器·前端·网络·安全
ShineWinsu10 小时前
对于JavaScript:JavaScript基础语法的解析
开发语言·前端·javascript·面试·web·基础语法·循环
月夏10 小时前
Vue3 转 React:18 项对照表 + 5 个必踩的坑(附 7 天上手路线)
前端
广州华水科技10 小时前
单北斗GNSS位移监测系统的应用与维护解析
前端
梦曦i10 小时前
uni-storage 0.1.0 发布:TTL过期管理+多实例隔离
前端·storage·uni-app x
猫头_11 小时前
AI 流式传输工程指南:模型吐出半截 JSON,前端如何边收边渲染?
前端·javascript·llm
console.log('npc')12 小时前
第 1 章 项目概述与环境搭建
前端·人工智能·大模型
定栓12 小时前
Webpack迁到Vite第七节(二):全家桶移除 — Babel 全家桶深度分析
前端·webpack·node.js