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 json2 使用方法
Mar 16 Javascript
FileUpload 控件 禁止手动输入或粘贴的实现代码
Apr 07 Javascript
javascript学习笔记(十九) 节点的操作实现代码
Jun 20 Javascript
JS实现图片放大镜效果的方法
Feb 27 Javascript
利用jQuery实现WordPress中@的ID悬浮显示评论内容
Dec 11 Javascript
JavaScript设计模式经典之命令模式
Feb 24 Javascript
jQuery实现下拉加载功能实例代码
Apr 01 Javascript
scroll事件实现监控滚动条并分页显示(zepto.js)
Dec 18 Javascript
详谈jQuery unbind 删除绑定事件 / 移除标签方法
Mar 02 Javascript
axios的拦截请求与响应方法
Aug 11 Javascript
移动端滑动切换组件封装 vue-swiper-router实例详解
Nov 25 Javascript
js中Function引用类型常见有用的方法和属性详解
Dec 11 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微信支付接口开发程序
2016/08/02 PHP
PHP实现大数(浮点数)取余的方法
2017/02/18 PHP
重载toString实现JS HashMap分析
2011/03/13 Javascript
jquery中.add()的使用分析
2013/04/26 Javascript
jquery 单引号和双引号的区别及使用注意
2013/07/31 Javascript
js将字符串转成正则表达式的实现方法
2013/11/13 Javascript
JQuery插件fancybox无法在弹出层使用左右键的解决办法
2013/12/25 Javascript
jquery自动将form表单封装成json的具体实现
2014/03/17 Javascript
javascript去除字符串中所有标点符号和提取纯文本的正则
2014/06/07 Javascript
JavaScript支持的最大递归调用次数分析
2014/06/24 Javascript
JavaScript中的索引数组、关联数组和静态数组、动态数组讲解
2014/11/08 Javascript
CSS javascript 结合实现悬浮固定菜单效果
2015/08/23 Javascript
javascript实现图片左右滚动效果【可自动滚动,有左右按钮】
2016/09/19 Javascript
angular基于路由控制ui-router实现系统权限控制
2016/09/27 Javascript
JS控制TreeView的结点选择
2016/11/11 Javascript
实现div滚动条默认最底部以及默认最右边的示例代码
2017/11/15 Javascript
妙用缓存调用链实现JS方法的重载
2018/04/30 Javascript
vue-swiper的使用教程
2018/08/30 Javascript
mock.js实现模拟生成假数据功能示例
2019/01/15 Javascript
Vue源码探究之虚拟节点的实现
2019/04/17 Javascript
在博客园博文中添加自定义右键菜单的方法详解
2020/02/05 Javascript
[03:59]第二届DOTA2亚洲邀请赛选手传记-VGJ.rOtk
2017/04/03 DOTA
Python实现二叉搜索树
2016/02/03 Python
Python实现的桶排序算法示例
2017/11/29 Python
mac 安装python网络请求包requests方法
2018/06/13 Python
tensorflow实现加载mnist数据集
2018/09/08 Python
Python编程中flask的简介与简单使用
2018/12/28 Python
python如何解析配置文件并应用到项目中
2019/06/27 Python
Python反爬虫伪装浏览器进行爬虫
2020/02/28 Python
django日志默认打印request请求信息的方法示例
2020/05/17 Python
清洁工岗位职责
2014/01/29 职场文书
中学生运动会新闻稿
2014/09/24 职场文书
学校政风行风评议工作总结
2014/10/21 职场文书
Golang: 内建容器的用法
2021/05/05 Golang
解决MySQL添加新用户-ERROR 1045 (28000)的问题
2022/03/03 MySQL
【DOTA2】总决赛血虐~ XTREME GAMING vs MAGMA - OGA DOTA PIT 2022 CN
2022/04/02 DOTA