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 相关文章推荐
你需要知道的JavsScript可以做什么?
Jun 29 Javascript
JavaScript delete操作符应用实例
Jan 13 Javascript
JavaScript 设计模式 富有表现力的Javascript(一)
May 26 Javascript
js getElementsByTagName的简写方式
Jun 27 Javascript
JS插件overlib用法实例详解
Dec 26 Javascript
关于json字符串与实体之间的严格验证代码
Nov 10 Javascript
JavaScript队列、优先队列与循环队列
Nov 14 Javascript
使用base64对图片的二进制进行编码并用ajax进行显示
Jan 03 Javascript
在Vue项目中使用d3.js的实例代码
May 01 Javascript
基于vue.js实现分页查询功能
Dec 29 Javascript
JS实现打砖块游戏
Feb 14 Javascript
原生JavaScript实现购物车
Jan 10 Javascript
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无限分类(树形类)的深入分析
2013/06/02 PHP
php多层数组与对象的转换实例代码
2013/08/05 PHP
yii2中使用Active Record模式的方法
2016/01/09 PHP
一段实时更新的时间代码
2006/07/07 Javascript
解javascript 混淆加密收藏
2009/01/16 Javascript
基于jquery的loading 加载提示效果实现代码
2011/09/01 Javascript
浅谈javascript六种数据类型以及特殊注意点
2013/12/20 Javascript
javascript字母大小写转换的4个函数详解
2014/05/09 Javascript
微信JSSDK上传图片
2015/08/23 Javascript
理解javascript中DOM事件
2015/12/25 Javascript
sencha ext js 6 快速入门(必看)
2016/06/01 Javascript
详解Vue 普通对象数据更新与 file 对象数据更新
2017/04/26 Javascript
通过vue提供的keep-alive减少对服务器的请求次数
2018/04/01 Javascript
VueJS 组件参数名命名与组件属性转化问题
2018/12/03 Javascript
小程序实现层叠卡片滑动效果
2019/08/26 Javascript
如何正确理解vue中的key详解
2019/11/02 Javascript
vue.js 子组件无法获取父组件store值的解决方式
2019/11/08 Javascript
python 全局变量的import机制介绍
2017/09/07 Python
python 列表降维的实例讲解
2018/06/28 Python
python 二维数组90度旋转的方法
2019/01/28 Python
基于django传递数据到后端的例子
2019/08/16 Python
Pytorch之contiguous的用法
2019/12/31 Python
解决pycharm同一目录下无法import其他文件
2020/02/12 Python
浅谈keras使用中val_acc和acc值不同步的思考
2020/06/18 Python
使用CSS3的appearance属性改变元素的外观的方法
2015/12/12 HTML / CSS
html5+css3之制作header实例与更新
2020/12/21 HTML / CSS
canvas简易绘图的实现(海绵宝宝篇)
2018/07/04 HTML / CSS
美国婴童服装市场上的领先品牌:Carter’s
2018/02/08 全球购物
大学生毕业求职简历的自我评价
2013/10/24 职场文书
运动会通讯稿50字
2014/01/30 职场文书
《飞向蓝天的恐龙》教学反思
2014/04/09 职场文书
活动总结报告范文
2014/05/04 职场文书
外贸业务员求职信
2014/06/16 职场文书
感恩祖国演讲稿
2014/09/09 职场文书
员工手册董事长致辞
2015/07/29 职场文书
MySQL控制流函数(-if ,elseif,else,case...when)
2022/07/07 MySQL