JS007. 深入探讨带浮点数运算丢失精度问题(二进制的浮点数存储方式)
复现与概述
当JS在进行浮点数运算时可能产生丢失精度的情况:

从肉眼可见的程度上观察,发生精度丢失的浮点数是没有规律的,但该浮点数丢失精度的问题会100%复现。经查阅,这个问题要追溯至浮点数的二进制存储方式,然而就高数而言,无限接近1的0.999999…和1是等价的,1 / ∞ ≈ 0 同理,在二进制中也同样存在这一情况。
找到原因
现在寻找浮点数的精度丢失问题跟二进制存储到底存在什么联系。
JavaScript引擎 - v8核心代码中,对于小数存储位双精度浮点,即64位保存的,但是这64位又分为三部分:

由于52位尾数用于记录数值,所以前端的精准位数应该是2^53-1即15位。当超过15位的时候就会出现精度损失。
例如小数2.55的储存方式:

最后的52位是一个1000110011001100的有限循环,但对于计算机来说,可以微妙的察觉到上文提到的两对参数失精问题大概就是由此而来:

再谈谈toFixed(n),它的处理方式就是在尾数位上减去第n位以外的小数,然后判断剩下的尾数是否大于2^-(n+1),大于等于就进位,小于等于就不进位。例如:
2.55.toFixed(1) 0 10000000000 0100011001100110011001100110011001100110011001100110
- 01000000000000000000000000000000000000000000000000
= 0000011001100110011001100110011001100110011001100110
然而 0000011001100110011001100110011001100110011001100110 即 0.000011001100110011001100110011001100110011001100110 = 0.04999999999999982236431605997495353221893310546875 < 2^-2=0.05
也就是说不会进位,实际上v8核心是通过尾数移位并通过某一个指定的标志位是否为1来判断进位的。
解决方法
百度上已经有许多封装好的成熟代码,基本围绕着重写 Number.prototype.toFixed( ) 解决,本文不在赘述。
此处贴上一个觉得靠谱的toFixed( ) 重写文章: js toFixed失去精度问题
版权声明:本文提到的外链皆为原作者原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
JS007. 深入探讨带浮点数运算丢失精度问题(二进制的浮点数存储方式)的更多相关文章
- JS 浮点数运算丢失精度解决方案
除法 function accDiv(arg1,arg2){ var t1=0,t2=0,r1,r2; try{t1=arg1.toString().split(".")[1].l ...
- JavaScript浮点数运算的精度问题
之前在做浮点数计算时,偶然发现计算结果有误差,度娘了解了下,补充整理了下. 误差是什么样子的呢?举例 console.log(0.1+0.2); // 0.30000000000000004 事实上在 ...
- 浮点数运算的精度问题:以js语言为例
在 JavaScript 中整数和浮点数都属于 Number 数据类型,所有数字都是以 64 位浮点数形式储存,即便整数也是如此. 所以我们在打印 1.00 这样的浮点数的结果是 1 而非 1.00 ...
- JavaScript 浮点数运算的精度问题
问题描述 在 JavaScript 中整数和浮点数都属于 Number 数据类型,所有数字都是以 64 位浮点数形式储存,即便整数也是如此. 所以我们在打印 1.00 这样的浮点数的结果是 1 而非 ...
- Java使用BigDecimal解决浮点型运算丢失精度的问题
@Test public void test1(){ System.out.print(0.05+0.01); } @Test public void test2(){ BigDecimal b1 = ...
- Number浮点数运算详解
文章来自我的 github 博客,包括技术输出和学习笔记,欢迎star. 一道题 0.1 + 0.2 = ? 在浏览器中测试下计算结果,得到的结果是 0.30000000000000004,并不是理想 ...
- js,java,浮点数运算错误及应对方法
js,java浮点数运算错误及应对方法 一,浮点数为什么会有运算错误 IEEE 754 标准规定了计算机程序设计环境中的二进制和十进制的浮点数自述的交换.算术格式以及方法. 现有存储介质都是2进制.2 ...
- JavaScript 浮点数运算 精度问题
JavaScript小数在做四则运算时,精度会丢失,这会在项目中引起诸多不便,先请看下面脚本. //加减 <script type="text/javascript" lan ...
- PHP浮点数运算精度造成的,订单金额支付经常少1分的问题
最近碰见一个奇怪的问题,商城通过微信支付的订单经常少一分钱,经过排查是PHP浮点运算精度问题造成的 由PHP浮点数运算精度造成的,鸟哥的Bolg有详细的说明.http://www.laruence.c ...
随机推荐
- 洛谷P1377题解
题面 首先他叫我们建一颗笛卡尔树,所以我们就建一颗笛卡尔树. 然后他说要生成序列中最小的.想到笛卡尔树的一条性质:左<根<右.但是根节点必须先插进去.他的两个儿子用贪心的思想就知道是先选左 ...
- MySQL 优化特定类型的查询
优化COUNT()查询 COUNT() 是一个特殊的函数,有两种非常不同的作用: 统计某个列值的数量,也可以统计行数.在统计列值时要求列值是非空的(不统计NULL ).如果在COUNT() 的括号中指 ...
- python自动化之(自动生成测试报告)
前言: 用python执行测试脚本, 测试报告是记录我们测试过程的问题, 方便我们对整个测试过程的把控. 这里引用的是别人写好的模板, 我们拿过来用就OK, 能力强者可自行编写模板 测试报告图模板: ...
- C++STL—string类
string容器 1.1 string容器的基本概念 string容器是一个类 这个容器中有一个指针,指针维护了一个数组 string容器提供copy.find.insert.replace等等功能 ...
- 网络图片下载,commons IO包
网络图片下载,commons IO包 导入commons-io包 commons-io包下载路径: http://www.apache.org/ 项目下新建lib包,将lib包添加为库 实现多线程下载 ...
- [SQL]数据更新
插入数据 插入单个元组 一般格式: insert into <表名> [<列名1>, <列明2>, --] -- 指出在表中新插入的值的列, values(< ...
- Crash course statistics
Crash course statistics 01什么是统计学 描述性统计(Descriptive statistics) 推理统计可以得出之外的,基于"样本"的推论统计学来估计 ...
- ES6继承和ES5继承是完全一样的么?
继承方式 ES5 prototype 继承 通过原型链(构造函数 + [[prototype]])指向实现继承. (备注:后续__proto__我都会写成[[prototype]]这种形式) 子类的 ...
- NOIP 模拟 $29\; \rm 最长不下降子序列$
题解 \(by\;zj\varphi\) 观察这个序列,发现模数很小,所以它的循环节很小. 那么可以直接在循环节上做最长上升子序列,但是循环节中的逆序对会对拼接后的答案造成影响. 没有必要找逆序对个数 ...
- SpringBoot 指定用户退出登录
HttpSessionConfig.java package com.meeno.common.session; import com.meenoframework.common.filter.Ses ...