JS中关于0.1+0.2 !==0.3 和0.1+0.7!==0.8的问题
**
JS中关于0.1+0.2 !==0.3 和0.1+0.7!==0.8的问题
**
在js中,0.1+0.2不会等于0.3,而是等于:
在js中,0.1+0.7不会等于0.8,而是等于:
JS中数字运算时,有一个叫做 数字运算中的精度缺失的问题
要弄清这个问题的原因,首先我们需要了解下在计算机中数字是如何存储和运算的。在计算机中,数字无论是定点数还是浮点数都是以多位二进制的方式进行存储的。
在JS中数字采用的IEEE 754的双精度标准进行存储,我们可以无需知道他的存储形式,只需要简单的理解成就是存储一个数值所使用的二进制位数比较多而已,这样得到的数会更加精确。
这里为了简单直观,我们使用定点数来说明问题。在定点数中,如果我们以8位二进制来存储数字。
对于整数来说,十进制的35会被存储为: 00100011 其代表 2^5 + 2^1 + 2^0。
对于纯小数来说,十进制的0.375会被存储为: 0.011 其代表 1/2^2 + 1/2^3 = 1/4 + 1/8 = 0.375
而对于像0.1这样的数值用二进制表示你就会发现无法整除,最后算下来会是 0.000110011…由于存储空间有限,最后计算机会舍弃后面的数值,所以我们最后就只能得到一个近似值。
在JS中采用的IEEE 754的双精度标准也是一样的道理,我们且不管这个标准下的存储方式跟定点数存储有何不同,单单在这一点上他们都是相同的,也就是存储空间有限,当出现这种无法整除的小数的时候就会取一个近似值,在js中如果这个近似值足够近似,那么js就会认为他就是那个值。
在0.1 + 0.2这个式子中,0.1和0.2都是近似表示的,在他们相加的时候,两个近似值进行了计算,导致最后得到的值是0.30000000000000004,此时对于JS来说,其不够近似于0.3,于是就出现了0.1 + 0.2 != 0.3 这个现象。 当然,也并非所有的近似值相加都得不到正确的结果。
有时两个近似值进行计算的时候,得到的值是在JS的近似范围内的,于是就可以得到正确答案。至于哪些值计算后能得到正确结果,哪些不能,我们也不需要去记。
最好的方法就是我们想办法规避掉这类小数计算时的精度问题就好了,那么最常用的方法就是将浮点数转化成整数计算。因为整数都是可以精确表示的。
那怎么去解决这个bug,让这两个式子成立呢?
方法一
最简单的就是先把0.1和0.2换成别的数字(因为在js中只有这两个数相加有bug,例如:1.1+1.2不会有问题),所以先让0.1和0.2分别乘以10,求和之后再除以10 ,则不会有问题:
(0.110+0.210)/10 ===0.3
方法二
可能很多小伙伴都忘记了js的Number对象有一个保留小数位数的方法:toFixed();传入一个需要保留的位数就OK:
parseFloat((0.1+0.2).toFixed(10)) ===0.3
因为toFixed方法返回的是一个字符串,所以别忘了把字符串转回浮点数。
方法一
最简单的就是先把0.1和0.2换成别的数字(因为在js中只有这两个数相加有bug,例如:1.1+1.2不会有问题),所以先让0.1和0.2分别乘以10,求和之后再除以10 ,则不会有问题:
(0.110+0.210)/10 ===0.3
方法二
可能很多小伙伴都忘记了js的Number对象有一个保留小数位数的方法:toFixed();传入一个需要保留的位数就OK:
parseFloat((0.1+0.2).toFixed(10)) ===0.3
因为toFixed方法返回的是一个字符串,所以别忘了把字符串转回浮点数。
JS中关于0.1+0.2 !==0.3 和0.1+0.7!==0.8的问题相关推荐
- js中关于带数字类型参数传参丢失首位数字0问题
最近在项目中遇到一个问题,js中传带有数字的参数时,如果参数开头有数字0,会把0给去掉. 例如: 方法abc(0123456,789); 方法abc中获取的参数0123456就会变为123456. 原 ...
- java中如何设置浏览器宽度_[Java教程]关于JS中获取浏览器高度和宽度值的多种方法(多浏览器)_星空网...
关于JS中获取浏览器高度和宽度值的多种方法(多浏览器) 2017-08-07 0 三种浏览器获取值方法 IE中: document.body.clientWidth ==> BODY对象宽度 d ...
- js中的强制类型转换和进制数表达
强制的类型转换: String的转换 var a = 123;console.log(typeof a); //stringconsole.log(a); //123 方式一: ----调用被转换类型 ...
- js中对特殊字符进行转义
js中对一些特殊字符进行转义 addEscape(value) {let arr = ['(', '[', '{', '/', '^', '$', '¦', '}', ']', ')', '?', ' ...
- js中的关键字总结呢
1.document.write(""); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document->html->(head,body) 4. ...
- js中遍历数组的6种方式
1.原生js中for循环 var arr=[1,2,3,4,5];for(var i=0;i<arr.length;i++){console.log(arr[i]) //打印每一个数组元素} 2 ...
- JS 中实现鼠标长按连续触发
<!DOCTYPE html> <html><head><title>JS中实现鼠标长按连续触发</title></head>& ...
- JS中的null和undefined,undefined为啥用void 0代替?
起因 某天,在看某位同学的js代码,代码中发现了一个奇怪的东西 void 0,虽然第一眼看不懂这是什么东西,但是根据上下文,这里应该是想判断是否等于undefined,为什么要这样写的,有什么渊源 ...
- js中判断-0 ,js无穷数Infinity
var z = 1/0 var o = -1/0 console.log(z, o)var a = Number("-0") console.log("%c" ...
- 为什么js中要用void 0 代替undefined
这个是Backbone.js中的一句源码 if (callback !== void 0 && 'context' in opts && opts.context == ...
最新文章
- 微软网站开始出现大量的关于Office 2007的相关下载
- 使用pycharm调试Python代码时F8快捷键失效
- AngularJS学习笔记(一)
- 【安卓开发 】Android初级开发(七)MD5加密
- python正则表达式入门_Python中的正则表达式教程
- Magento 架构原则
- 大公司的资深工程师和小公司的Leader如何决择?
- arcgis dem栅格立体感_arcgis中DEM如何生成等高线
- JavaScript高级程序设计(第三版)pdf的下载地址
- 触摸屏与单片机通讯C语言程序,讲述如何实现单片机与触摸屏的通信
- Primer C++(第5版)PDF
- c++ 开根号程序 算法实现 C++函数同时返回两个值
- 统计学理论—一元线性回归
- Canvas绘制地图
- 亚马逊云服务(AWS)机器学习服务Amazon SageMaker发力中国
- 虚拟主机换云服务器,云虚拟主机想换云服务器
- SSO(Single Sign On)系列(一)--SSO简介
- c语言输出函数语句,c语言输出语句及格式输出函数介绍
- 多线程是啥?有啥用?(上)
- dhcp服务器设置(路由器dhcp服务器怎么设置)
热门文章
- Web前端第四季(jQuery):四:301-jQuery基本过滤器(奇数和偶数)+302-实现隔行换色+401-祖先选择器和子代选择器
- 自主导航小车实践(三)
- eclipse web开发 AJAX实例以及URL和Tomcat细节
- MathType工具栏tool不小心拖出来
- 人造器官新突破!美国科学家3D打印出会“呼吸”的肺 | Science
- smalldatetime mysql_SQLSERVER中datetime和smalldatetime类型分析说明
- 微信开发纪实之历史上的今天服务
- css3-旋转的星球
- 世界上最没用的几句话
- linux下无对应分辨率,关于linux 下显示分辨率问题1440*900?