摘要:就像一些无理数不能有限表示,如圆周率,等。遵循规范,采用双精度存储,占用。参考中不会失去精度的最大值数字精度丢失的一些典型问题
问题描述
后端返回 { spaceObject: { objectId: "1049564069045993472" } }
前端模版,使用的是 atpl 模版
前端获取 objectId 的方式,const objectId = $("#test").data("id")
正常理解,我们获取到的 objectId 就是返回的 1049564069045993472,可是现实情况是这个 objectId 是 1049564069045993500
问题拆分 一,为什么从 dom 中获取的字符串会变成数字查看 zepto 代码可知,由于通过 $("#test").data("id") 获取到的字符串 "1049564069045993472" 经过 deserializeValue 方法之后就变成数字了。
关键代码如下:
data: function (name, value) { //[Opt:C]将原本在父级作用域的变量转移至局部变量 var capitalRE = /([A-Z])/g, data = this.attr("data-" + name.replace(capitalRE, "-$1").toLowerCase(), value) return data !== null ? deserializeValue(data) : undefined }, // "true" => true // "false" => false // "null" => null // "42" => 42 // "42.5" => 42.5 // "08" => "08" // JSON => parse if valid // String => self function deserializeValue(value) { var num try { return value ? value == "true" || ( value == "false" ? false : value == "null" ? null : !/^0/.test(value) && !isNaN(num = Number(value)) ? num : /^[[{]/.test(value) ? $.parseJSON(value) : value ) : value } catch (e) { return value } }二,为什么数字跟 dom 中获取的不一致
由于javascript的能够保持精度的最大值是 9007199254740991,所以由于上面那个数字大于这个最大安全数,所以会出现失去精度的问题。
引申 javascript 中精度丢失的几种情况 1. 简单的浮点数相加0.1 + 0.2 !== 0.3 // true
0.1 + 0.2 === 0.3 // false
)
99999999999999999 === 100000000000000000
(12.235).toFixed(2) // 12.23
首先,javascript 中保持精度不丢失的数值是有个范围的,是在 Number.MIN_SAFE_INTEGER 和 Number.MAX_SAFE_INTEGER 之间. Number.MAX_SAFE_INTEGER => 9007199254740991 => 2的53次方-1
ECMA Section 8.5 - Numbers Note that all the positive and negative integers whose magnitude is no greater than 253 are representable in the Number type (indeed, the integer 0 has two representations, +0 and −0).
计算机的二进制实现和位数限制有些数无法有限表示。就像一些无理数不能有限表示,如 圆周率 3.1415926...,1.3333... 等。JS 遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit。如图
* 1位用来表示符号位 * 11位用来表示指数 * 52位表示尾数
深入了解
解决方案使用 big.js库
如果是小数加减可以通过先将所有小数转化为整数(乘倍数),然后完成运算,最后缩小回去(除倍数)。
0.01 + 0.2 // 0.21000000000000002 (0.01 * 100 + 0.2 * 100) / 100 // 0.21参考
javascript 中不会失去精度的最大值
JS数字精度丢失的一些典型问题
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/98303.html
摘要:前言在数据敏感的业务场景中,常常会碰到数据精度问题,尤其在金额显示占比统计等地方,该问题尤为显著。计算机原理真香数值的精度问题,其实是非常基础的计算机原理知识。前言 在数据敏感的业务场景中,常常会碰到数据精度问题,尤其在金额显示、占比统计等地方,该问题尤为显著。由于数据的每一位有效数字都包含真实的业务语义,一点点偏差甚至可能影响业务决策,这让问题的严重性上升了几个阶梯。 那,什么是精度丢失...
摘要:如题先陈述下问题背景偶尔测测自己写的计算器,随便输入玩嘛,然后发生下面诡异的事情当我从一个输入到十个的时候,过程显示都是正确的,像这样继续输入一个的时候,然后就这个样子了什么原因呢看了下自己的代码,代码重要部分长这样的这里用了一下强制转化为 如题 先陈述下问题背景 偶尔测测自己写的计算器,随便输入玩嘛,然后发生下面诡异的事情:当我从一个 1 输入到十个 1 的时候,过程显示都是正确的...
摘要:推导为何等于在中所有数值都以标准的双精度浮点数进行存储的。先来了解下标准下的双精度浮点数。精度位总共是,因为用科学计数法表示,所以首位固定的就没有占用空间。验证完成的最大安全数是如何来的根据双精度浮点数的构成,精度位数是。 阅读完本文可以了解到 0.1 + 0.2 为什么等于 0.30000000000000004 以及 JavaScript 中最大安全数是如何来的。 十进制小数转为二...
摘要:如图意义位用来表示符号位位用来表示指数位表示尾数浮点数,比如无限循环无限循环此时只能模仿十进制进行四舍五入了,但是二进制只有和两个,于是变为舍入。这即是计算机中部分浮点数运算时出现误差,丢失精度的根本原因。 showImg(http://ww1.sinaimg.cn/large/9c47d583gy1fmtw1ma9g4j21hc0u0ach.jpg); 前言 最近一直有小伙伴跟我说J...
摘要:前言最近,朋友问了我这样一个问题在中的运算结果,为什么是这样的虽然我告诉他说,这是由于浮点数精度问题导致的。由于可以用阶码移动小数点,因此称为浮点数。它的实现遵循标准,使用位精度来表示浮点数。 showImg(https://segmentfault.com/img/remote/1460000018981071); 前言 最近,朋友 L 问了我这样一个问题:在 chrome 中的运算...
阅读 975·2021-11-23 09:51
阅读 2290·2021-10-08 10:22
阅读 2467·2021-09-29 09:35
阅读 824·2021-09-22 15:20
阅读 2827·2019-08-30 15:53
阅读 2385·2019-08-30 13:55
阅读 1055·2019-08-29 17:27
阅读 2838·2019-08-29 17:26