如何解决JavaScript中0.1+0.2不等于0.3
console.log(0.1+0.2===0.3)// true or false??
在正常的数学逻辑思维中,0.1+0.2=0.3这个逻辑是正确的,但是在JavaScript中0.1+0.2!==0.3,这是为什么呢?这个问题也会偶尔被用来当做面试题来考查面试者对
JavaScript的数值的理解程度。
在JavaScript中的二进制的浮点数0.1和0.2并不是十分精确,在他们相加的结果并非正好等于0.3,而是一个比较接近的数字 0.30000000000000004 ,所以条件判断结果为 false。
那么应该怎样来解决0.1+0.2等于0.3呢? 最好的方法是设置一个误差范围值,通常称为”机器精度“,而对于Javascript来说,这个值通常是2^-52,而在ES6中,已经为我们提供了这样一个
属性:Number.EPSILON,而这个值正等于2^-52。这个值非常非常小,在底层计算机已经帮我们运算好,并且无限接近0,但不等于0,。这个时候我们只要判断(0.1+0.2)-0.3小于
Number.EPSILON,在这个误差的范围内就可以判定0.1+0.2===0.3为true。
function numbersequal(a,b){
return Math.abs(a-b)<Number.EPSILON;
} var a=0.1+0.2, b=0.3;
console.log(numbersequal(a,b)); //true
但是这里要考虑兼容性的问题了,在chrome中支持这个属性,但是IE并不支持(笔者的版本是IE10不兼容),所以我们还要解决IE的不兼容问题。
Number.EPSILON=(function(){ //解决兼容性问题
return Number.EPSILON?Number.EPSILON:Math.pow(2,-52);
})(); //上面是一个自调用函数,当JS文件刚加载到内存中,就会去判断并返回一个结果,相比if(!Number.EPSILON){
// Number.EPSILON=Math.pow(2,-52);
//}这种代码更节约性能,也更美观。 function numbersequal(a,b){
return Math.abs(a-b)<Number.EPSILON;
} //接下来再判断 var a=0.1+0.2, b=0.3;
console.log(numbersequal(a,b)); //这里就为true了
这个是二进制浮点数最大的问题(不仅 JavaScript,所有遵循 IEEE 754 规范的语言都是如此)。
注意:有人认为,JavaScript 应该采用一种可以精确呈现数字的实现方式。一直以来出现过很多替代方案,只是都没能成为标准,以后大概也不会。这个问题看似简单,实则不
然,否则早就解决了。
问题是,如果一些数字无法做到完全精确,是否意味着数字类型毫无用处呢?答案当然是否定的。
在处理带有小数的数字时需要特别注意。很多(也许是绝大多数)程序只需要处理整数,最大不超过百万或者万亿,此时使用 JavaScript 的数字类型是绝对安全的。
如何解决JavaScript中0.1+0.2不等于0.3的更多相关文章
- 深入理解JavaScript系列:为什么03-0.2不等于0.1
五一宅家看书,所以接着更新一篇文章. 今天讲一下为什么03-0.2不等于0.1这个问题. 有点标题党的味道,在JavaScript中,当你试着对小数进行加减运算时,有时候会发现某个结果并非我们所想的那 ...
- 解决JavaScript中构造函数浪费内存的问题!
解决JavaScript中构造函数浪费内存的问题! 把构造函数中的公共的方法放到构造函数的原型对象上! // 构造函数的问题! function Gouzaohanshu(name, age, gen ...
- JavaScript中的ParseInt("08")和“09”返回0的原因分析及解决办法
今天在程序中出现一个bugger ,调试了好久,最后才发现,原来是这个问题. 做了一个实验: alert(parseInt("01")),当这个里面的值为01====>07时 ...
- Javascript中的undefined、null、""、0值和false的区别总结
在程序语言中定义的各种各样的数据类型中,我们都会为其定义一个"空值"或"假值",比如对象类型的空值null,.NET Framework中数据库字段的空值DBN ...
- Javascript中那些你不知道的事之-- false、0、null、undefined和空字符串
话不多说直接进入主题:(如果有写的不对的地方欢迎指正) 我们先来看看他们的类型分别是什么: typeof类型检测结果 结论:false是布尔类型对象,0是数字类型对象,null是object对象,un ...
- JavaScript中登录名的正则表达式及解析(0基础)
简言 在JavaScript中,经常会用到正则表达式来进行模式匹配.例如,登录名验证,密码强度验证,字符串查找或替换等操作.现在就开始吧,零基础写出你的第一个正则表达式! 在做用户注册时,都会用到登录 ...
- 解决Win10 中打开VS2012 出现“ASP.NET 4.0 尚未在 Web 服务器上注册”
系统升级为win10后,在使用vs2012打开原来的项目时,会出现“ASP.NET 4.0 尚未在 Web 服务器上注册”的问题,如图: 想到在win8.1系统下,也出现过同样的问题,就直接使用命令提 ...
- 查表法解决calendar中月份及星期初始值为0的情况。
Calendar ca = Calendar.getInstance(); String [] index = {"星期一","星期二","星期三&q ...
- 解决Javascript中$(window).resize()多次执行
有些时候,我们需要在浏览器窗口发生变化的时候,动态的执行一些操作,比如做自适应页面时的适配.这个时候,我们需要在窗口拖动的时候去执行代码.但是有些时候,执行的操作比较复杂,我们只希望在窗口拖动完毕之后 ...
随机推荐
- input[type=file]中使用ajaxSubmit来图片上传
今天在使用input[type=file]上传图片到服务器时,因为项目要求,并不是像常见的通过按钮来提交表单事件,而是图片上传后就自动执行表单提交事件,将上传的图片信息传给服务器. 刚开始我是这样执行 ...
- EC+VO+SCOPE for ES3
词法环境 词法作用域 词法作用域(lexcical scope).即JavaScript变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码. 词法环境 用于定义特定变量和函数标识 ...
- thinkphp操作完提示信息该怎么弄成弹出层啊?
http://www.thinkphp.cn/topic/21929.html 浏览:11879 发布日期:2014/08/22 分类:求助交流 关键字: thinkphp success跳转 弹出层 ...
- vue 入门第一课
windows安装git 安装淘宝镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org 全局安装vue cnpm inst ...
- asp.net -mvc框架复习(10)-基于三层架构与MVC搭建项目框架
一.三种模式比较 1.MVC框架(适合大型项目) (1).V视图 (网页部分) (2).M模型 (业务逻辑+数据访问+实体类) (3).C控制器 (介于M和V之间,起到引导作用) 2.三层架构 (1) ...
- AF_INET 和PF_INET区别;AF_LOCAL PF_LOCAL 区别.
从字面理解: AF_INET = Address Format, Internet = IP Addresses PF_INET = Packet Format, Internet = IP, TCP ...
- CSS深入理解学习笔记之margin
1.margin与容器尺寸 元素尺寸:①可视尺寸 clientWidth(标准):②占据尺寸 margin与可视尺寸:①适用于没有设定width/height的普通block元素:②只适用于水平方向尺 ...
- BSA Network Shell系列-通过NSH执行Powershell,VBScript或bat files脚本
参考:Running Powershell, VBScript, or bat files via NSH 如果你直接在NSH命令行执行的话,可以参考我翻译的下面的东东,如果想运行NSH 脚本作业的话 ...
- 自己写的日志框架--linkinLog4j--框架可配置+提性能
OK,上一篇博客我们已经实现了日志框架的基本的功能,但是还有一个最大的问题就是日志输出地不能重定向,然后一些输出也不可控.那现在我们来实现一个比较完整的日志框架. 设计思路如下: 1,定义一堆常量Li ...
- Servlet--j2e中文乱码解决
我们在写项目的时候经常会传递一些中文参数,但是j2e默认使用ISO-8859-1来编码和解码,所以很容易出现中文乱码问题.这里我做一个统一的整理,其实这里的中文乱码问题和上一篇的路径问题都是j2e经常 ...