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 ...
随机推荐
- Java架构师-十项全能学习笔记(1)
Java架构师-十项全能学习笔记(1) @Configuration @EnableStateMachine public class OrderStateMachineConfig extends ...
- MySQL 中删除的数据都去哪儿了?
不知道大家有没有想过下面这件事? 我们平时调用 DELETE 在 MySQL 中删除的数据都去哪儿了? 这还用问吗?当然是被删除了啊 那么这里又有个新的问题了,如果在 InnoDB 下,多事务并发的情 ...
- C++ 结构体案例2 升序打印数组中的元素
1 //结构体案例 2 2 #include<iostream> 3 #include<string> 4 #include<ctime> 5 using name ...
- 月薪20k+的Android面试都问些什么?(含答案)
金九银十跳槽季接近尾声了,可是今年由于疫情的影响仍然不太好找工作,相信大家肯定急需一套Android面试宝典,下面就分享给大家我珍藏已久的Android高阶面试宝典,供大家学习 ! 1.自定义Hand ...
- 一周内被程序员疯转3.2W次,最终被大厂封杀的《字节跳动Android面试手册》!
一眨眼又到金三银四了,不知道各位有没有做好跳槽涨薪的准备了呢? 今天的话大家分享一份最新的<字节跳动Android面试手册>,内容包含Android基础+进阶,Java基础+进阶,数据结构 ...
- Kotlin高阶函数实战
前言 1. 高阶函数有多重要? 高阶函数,在 Kotlin 里有着举足轻重的地位.它是 Kotlin 函数式编程的基石,它是各种框架的关键元素,比如:协程,Jetpack Compose,Gradle ...
- rancher清理主机脚本
#!/bin/bash #From:rancher #date:2019-10-18 #admin:jarno # 停止服务 systemctl disable kubelet.service sys ...
- DVWA(九):File Upload 全等级文件上传
File Upload 文件上传,通常是由于对上传文件的类型没有进行严格的过滤.限制造成的,一般思路是 通过上传木马获取服务器的webshell(通过网络端口对网站服务器某种程度上的操作权限 也叫网站 ...
- ARM—异常中断处理
文章目录 一. ARM程序执行流程 二. ARM工作模式 三. ARM中异常中断的种类 四. 异常中断向量表及优先级 五. 异常中断用到的寄存器 六. ARM进入处理异常中断时的操作 七. ARM退出 ...
- Proteus仿真—51单片机实现AC信号测频、显示、双机通信
文章目录 一.原理图部分 二.源码部分 单片机1 单片机2 在Proteus仿真软件里面使用STC89C52实现指定频率的AC信号的测频.显示.双机通信. 一.原理图部分 整体的电路图如示: DC-A ...