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 相关文章推荐
location.href语句与火狐不兼容的问题
Jul 04 Javascript
jquery的ajax请求全面了解
Mar 20 Javascript
如何实现textarea里的不同文本显示不同颜色
Jan 20 Javascript
jquery中$.post()方法的简单实例
Feb 04 Javascript
JS仿Windows开机启动Loading进度条的方法
Feb 26 Javascript
JavaScript中的原型prototype完全解析
May 10 Javascript
JavaScript使用forEach()与jQuery使用each遍历数组时return false 的区别
Aug 26 Javascript
Node.js中的require.resolve方法使用简介
Apr 23 Javascript
React学习笔记之条件渲染(一)
Jul 02 Javascript
Vuex实现计数器以及列表展示效果
Mar 10 Javascript
JS数组reduce()方法原理及使用技巧解析
Jul 14 Javascript
vue导入.md文件的步骤(markdown转HTML)
Dec 31 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
基于mysql的bbs设计(二)
2006/10/09 PHP
PHP整数取余返回负数的相关解决方法
2014/05/15 PHP
php页面跳转session cookie丢失导致不能登录等问题的解决方法
2016/12/12 PHP
JavaScript日历实现代码
2010/09/12 Javascript
jquery实现左右滑动菜单效果代码
2015/08/27 Javascript
Javascript 实现匿名递归的实例代码
2017/05/25 Javascript
angularjs实现搜索的关键字在正文中高亮出来
2017/06/13 Javascript
详解如何提高 webpack 构建 Vue 项目的速度
2017/07/03 Javascript
bootstrap table方法之expandRow-collapseRow展开或关闭当前行数据
2020/08/09 Javascript
nodejs实现截取上传视频中一帧作为预览图片
2017/12/10 NodeJs
Angular中管道操作符(|)的使用方法
2017/12/15 Javascript
angularjs 缓存的使用详解
2018/03/19 Javascript
微信小程序日历插件代码实例
2019/12/04 Javascript
基于JS实现table导出Excel并保留样式
2020/05/19 Javascript
JS实现移动端可折叠导航菜单(现代都市风)
2020/07/07 Javascript
原生JavaScript实现随机点名表
2021/01/14 Javascript
原生JavaScript实现进度条
2021/02/19 Javascript
[01:52]PWL S2开团时刻第四期——DOTA2成语故事
2020/12/03 DOTA
Python获取远程文件大小的函数代码分享
2014/05/13 Python
详解python3实现的web端json通信协议
2016/12/29 Python
python中类和实例如何绑定属性与方法示例详解
2017/08/18 Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
2019/03/30 Python
Pytorch 定义MyDatasets实现多通道分别输入不同数据方式
2020/01/15 Python
Pycharm中安装Pygal并使用Pygal模拟掷骰子(推荐)
2020/04/08 Python
Selenium基于PIL实现拼接滚动截图
2020/04/10 Python
Python在后台自动解压各种压缩文件的实现方法
2020/11/10 Python
matplotlib运行时配置(Runtime Configuration,rc)参数rcParams解析
2021/01/05 Python
html5中去掉input type date默认样式的方法
2018/09/06 HTML / CSS
大学毕业生求职自荐信
2014/02/20 职场文书
电子专业毕业生自荐信
2014/05/25 职场文书
应届大学生求职信
2014/07/20 职场文书
企业员工爱岗敬业演讲稿
2014/08/26 职场文书
组工干部演讲稿
2014/09/02 职场文书
车贷收入证明范本
2014/09/14 职场文书
MyBatis-Plus 批量插入数据的操作方法
2021/09/25 Java/Android
Java tomcat手动配置servlet详解
2021/11/27 Java/Android