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 ...
随机推荐
- C++ 1//设计立方体类 //创建立方体的类 //设计属性和行为 //获取立方体的面积和体积 //分别利用(全局函数 和 成员函数)判断俩个立方体是否相等
1 //设计立方体类 2 //创建立方体的类 3 //设计属性和行为 4 //获取立方体的面积和体积 5 //分别利用(全局函数 和 成员函数)判断俩个立方体是否相等 6 #include <i ...
- 阿里钉钉Android实习面试也太太太太难了吧,对算法的要求堪比字节
本人研究生在读,在2月26日找了师兄内推阿里钉钉团队,28号接到了约1面的电话.幸好我提前准备了一个多月的样子,刷面试题.刷LeetCode(面了之后才觉得自己刷少了),对于我这样一个实习生来说题目还 ...
- Golang语言系列-01-Go语言简介和变量
Go语言简介 Go(又称Golang)是Google开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言. 罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pi ...
- iOS开发之Video转GIF
前言 最近遇到需要将video转化为gif的问题,网上找的在线转换限制太多,索性就自己写了一个工具APP.文章末尾有开源代码和打包好的APP,如有需要请自行下载. 效果图 核心代码 来源 class ...
- swagger菜单分级
效果 实现 SwaggerAutoConfiguration里新增配置: package com.fxkj.common.config; import com.google.common.base.P ...
- 【工作篇】了解升级 Spring 版本导致的跨域问题
一.背景 最近需要统一升级 Spring 的版本,避免 common 包和各个项目间的 Spring 版本冲突问题.这次升级主要是从 Spring 4.1.9.RELEASE 升级到 Spring 4 ...
- NOIP 模拟 10 考试总结
T1 一道很妙的题,打暴力分也很多,但是考试的时候忘开 long long 了. 题解 T2 一道挺水的题,不过...(打挂了) 题解 T3 此题甚妙,转化真多,不过对思维是一个非常大的扩展 题解 考 ...
- noip 模拟9 题解
rp++==文化课报废 考试经过 先看T1,有被1e12吓到,但根据经验这很可能是水题,经过一番观察后直接打表,似乎看出了规律,觉得应该有了正解,写完之后顺利过掉大样例,但似乎时间稍慢一点,写上快读交 ...
- linux 系统文件记录
proc系列 /proc/diskstats # 记录磁盘相关信息 http://ykrocku.github.io/blog/2014/04/11/diskstats/
- 【springboot】validator枚举值校验
转自: https://blog.csdn.net/aiyaya_/article/details/78588200 一.前言 在spring项目中,校验参数功能使用hibernate validat ...