Javascript 浮点运算的问题分析与解决方法


Posted in Javascript onAugust 27, 2013

十进制           二进制
0.1              0.0001 1001 1001 1001 ...
0.2              0.0011 0011 0011 0011 ...
0.3              0.0100 1100 1100 1100 ...
0.4              0.0110 0110 0110 0110 ...
0.5              0.1
0.6              0.1001 1001 1001 1001 ...
所以比如 1.1 ,其程序实际上无法真正的表示 ‘1.1',而只能做到一定程度上的准确,这是无法避免的精度丢失:

1.09999999999999999
在JavaScript中问题还要复杂些,这里只给一些在Chrome中测试数据:

 输入               输出
1.0-0.9 == 0.1     False
1.0-0.8 == 0.2     False
1.0-0.7 == 0.3     False
1.0-0.6 == 0.4     True
1.0-0.5 == 0.5     True
1.0-0.4 == 0.6     True
1.0-0.3 == 0.7     True
1.0-0.2 == 0.8     True
1.0-0.1 == 0.9     True
解决
那如何来避免这类 1.0-0.9 != 0.1 的非bug型问题发生呢?下面给出一种目前用的比较多的解决方案, 在判断浮点运算结果前对计算结果进行精度缩小,因为在精度缩小的过程总会自动四舍五入:

(1.0-0.9).toFixed(digits)                   // toFixed() 精度参数须在 0 与20 之间
parseFloat((1.0-0.9).toFixed(10)) === 0.1   // 结果为True
parseFloat((1.0-0.8).toFixed(10)) === 0.2   // 结果为True
parseFloat((1.0-0.7).toFixed(10)) === 0.3   // 结果为True
parseFloat((11.0-11.8).toFixed(10)) === -0.8   // 结果为True

方法提炼
// 通过isEqual工具方法判断数值是否相等
function isEqual(number1, number2, digits){
 digits = digits == undefined? 10: digits; // 默认精度为10
 return number1.toFixed(digits) === number2.toFixed(digits);
}
isEqual(1.0-0.7, 0.3);  // return true
// 原生扩展方式,更喜欢面向对象的风格
Number.prototype.isEqual = function(number, digits){
 digits = digits == undefined? 10: digits; // 默认精度为10
 return this.toFixed(digits) === number.toFixed(digits);
}
(1.0-0.7).isEqual(0.3); // return true
Javascript 相关文章推荐
基于jQuery实现简单的折叠菜单效果
Nov 23 Javascript
深入解析JavaScript中的arguments对象
Jun 12 Javascript
深入理解JavaScript中的块级作用域、私有变量与模块模式
Oct 31 Javascript
简单理解vue中实例属性vm.$els
Dec 01 Javascript
基于javascript的Form表单验证
Dec 29 Javascript
jQuery在header中设置请求信息的方法
Mar 06 Javascript
Node.js EventEmmitter事件监听器用法实例分析
Jan 07 Javascript
Echarts动态加载多条折线图的实现代码
May 24 Javascript
layer更改皮肤的实现方法
Sep 11 Javascript
JS如何实现手机端输入验证码效果
May 13 Javascript
javascript实现贪吃蛇小练习
Jul 05 Javascript
详解Vue router路由
Nov 20 Vue.js
js中点击空白区域时文本框与隐藏层的显示与影藏问题
Aug 26 #Javascript
关于IE中getElementsByClassName不能用的问题解决方法
Aug 26 #Javascript
关于Jquery操作Cookie取值错误的解决方法
Aug 26 #Javascript
jquery弹出框的用法示例(2)
Aug 26 #Javascript
jquery弹出框的用法示例(一)
Aug 26 #Javascript
jQuery快速上手:写jQuery与直接写JS的区别详细解析
Aug 26 #Javascript
使用js实现雪花飘落效果
Aug 26 #Javascript
You might like
PHP多文件上传类实例
2015/03/07 PHP
thinkPHP中多维数组的遍历方法
2016/01/09 PHP
thinkphp3.2.0 setInc方法 源码全面解析
2018/01/29 PHP
PHP中检查isset()和!empty()函数的必要性
2019/02/13 PHP
js实现ASP分页函数 HTML分页函数
2006/09/22 Javascript
国外Lightbox v2.03.3 最新版 下载
2007/10/17 Javascript
JQuery中如何传递参数如click(),change()等具体实现
2013/04/28 Javascript
javascript中通过arguments参数伪装方法重载
2014/10/08 Javascript
JavaScript如何实现在文本框(密码框)输入提示语
2015/12/25 Javascript
jQuery对象与DOM对象转换方法详解
2016/05/10 Javascript
功能强大的Bootstrap使用手册(一)
2016/08/02 Javascript
详解Node.js中的事件机制
2016/09/22 Javascript
工作中常用到的ES6语法
2018/09/04 Javascript
nuxt中使用路由守卫的方法步骤
2019/01/27 Javascript
微信小程序自定义导航栏实例代码
2019/04/05 Javascript
vue路由中前进后退的一些事儿
2019/05/18 Javascript
[00:13]天涯墨客二技能展示
2018/08/25 DOTA
[02:12]Dota 2 推出全新英雄—— 电炎绝手
2019/08/23 DOTA
Python的Django框架下管理站点的基本方法
2015/07/17 Python
Fabric 应用案例
2016/08/28 Python
视觉直观感受若干常用排序算法
2017/04/13 Python
Python实现的下载网页源码功能示例
2017/06/13 Python
Opencv实现抠图背景图替换功能
2019/05/21 Python
使用python修改文件并立即写回到原始位置操作(inplace读写)
2020/06/28 Python
Python使用eval函数执行动态标表达式过程详解
2020/10/17 Python
利用html5 canvas破解简单验证码及getImageData接口应用
2013/01/25 HTML / CSS
美国在线眼镜店:GlassesShop
2018/11/15 全球购物
存储过程和函数的区别
2013/05/28 面试题
学生实习推荐信范文
2013/11/26 职场文书
大专生自我评价
2014/01/28 职场文书
平面设计求职信
2014/03/10 职场文书
运动会宣传口号
2014/06/09 职场文书
霸气押韵的班级口号
2014/06/09 职场文书
同步小康驻村工作简报
2015/07/20 职场文书
《英雄联盟》2022日蚀、月蚀皮肤演示 黑潮亚索曝光
2022/04/13 其他游戏
Win10 Anaconda安装python-pcl
2022/04/29 Servers