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 相关文章推荐
javascript 日历提醒系统( 兼容所有浏览器 )
Apr 07 Javascript
Javascript匿名函数的一种应用 代码封装
Jun 27 Javascript
事件模型在各浏览器中存在差异
Oct 20 Javascript
JavaScript中的Object对象学习教程
May 20 Javascript
JavaScript模仿Pinterest实现图片预加载功能
Oct 25 Javascript
js中setTimeout的妙用--防止循环超时
Mar 06 Javascript
详解vue组件基础
May 04 Javascript
IE9 elementUI文件上传的问题解决
Oct 17 Javascript
VUE引入第三方js包及调用方法讲解
Mar 01 Javascript
vue自定义指令用法经典实例小结
Mar 16 Javascript
解决layui数据表格Date日期格式的回显Object的问题
Sep 19 Javascript
浅析vue-router中params和query的区别
Dec 24 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
phpfans留言版用到的install.php
2007/01/04 PHP
修改php.ini实现Mysql导入数据库文件最大限制的修改方法
2007/12/11 PHP
加强版phplib的DB类
2008/03/31 PHP
Smarty模板学习笔记之Smarty简介
2014/05/20 PHP
PHP获取服务器端信息的方法
2014/11/28 PHP
php获取excel文件数据
2017/04/21 PHP
PHP使用preg_split和explode分割textarea存放内容的方法分析
2017/07/03 PHP
flexigrid 类似ext grid的JS表格代码
2010/07/17 Javascript
JavaScript中的View-Model使用介绍
2011/08/11 Javascript
jquery validate poshytip 自定义样式
2012/11/26 Javascript
jQuery实现DIV层淡入淡出拖动特效的方法
2015/02/13 Javascript
个人总结的一些JavaScript技巧、实用函数、简洁方法、编程细节
2015/06/10 Javascript
JQuery标签页效果的两个实例讲解(4)
2015/09/17 Javascript
Three.js快速入门教程
2016/09/09 Javascript
JavaScript数据结构之链表的实现
2017/03/19 Javascript
js手机号4位显示空格,银行卡每4位显示空格效果
2017/03/23 Javascript
JavaScript实现QQ列表展开收缩扩展功能
2017/10/30 Javascript
Node.js利用console输出日志文件的方法示例
2018/04/27 Javascript
vue监听对象及对象属性问题
2018/08/20 Javascript
vue中eslintrc.js配置最详细介绍
2018/12/21 Javascript
Element Card 卡片的具体使用
2020/07/26 Javascript
JS JQuery获取data-*属性值方法解析
2020/09/01 jQuery
全网小程序接口请求封装实例代码
2020/11/06 Javascript
[01:35]辉夜杯战队访谈宣传片—LGD
2015/12/25 DOTA
用python结合jieba和wordcloud实现词云效果
2017/09/05 Python
Python中的is和==比较两个对象的两种方法
2017/09/06 Python
python list转矩阵的实例讲解
2018/08/04 Python
对python requests的content和text方法的区别详解
2018/10/11 Python
详解python使用pip安装第三方库(工具包)速度慢、超时、失败的解决方案
2018/12/02 Python
python将excel转换为csv的代码方法总结
2019/07/03 Python
Tensorflow实现神经网络拟合线性回归
2019/07/19 Python
python并发编程多进程 互斥锁原理解析
2019/08/20 Python
python定义类self用法实例解析
2020/01/22 Python
2014年底工作总结
2014/12/15 职场文书
上级领导检查欢迎词
2015/09/30 职场文书
队列队形口号
2015/12/25 职场文书