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 相关文章推荐
用js实现计算加载页面所用的时间
Apr 02 Javascript
JQuery中关于jquery.js与jquery.min.js的比较探讨
May 15 Javascript
jQuery中index()的用法分析
Sep 05 Javascript
谈谈因Vue.js引发关于getter和setter的思考
Dec 02 Javascript
javascript稀疏数组(sparse array)和密集数组用法分析
Dec 28 Javascript
angular directive的简单使用总结
May 24 Javascript
Javascript防止图片拉伸的自适应处理方法
Dec 26 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
Oct 12 Javascript
vue单页面实现当前页面刷新或跳转时提示保存
Nov 02 Javascript
JavaScript实现动态留言板
Mar 16 Javascript
纯js+css实现在线时钟
Aug 18 Javascript
vue实现购物车的小练习
Dec 21 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 stream_context_create()作用和用法分析
2011/03/29 PHP
php学习笔记 数组的常用函数
2011/06/13 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十)
2014/06/24 PHP
详细解读PHP中接口的应用
2015/08/12 PHP
基于CI框架的微信网页授权库示例
2016/11/25 PHP
使用javascript访问XML数据的实例
2006/12/27 Javascript
js实现鼠标拖动图片并兼容IE/FF火狐/谷歌等主流浏览器
2013/06/06 Javascript
浅析node.js中close事件
2014/11/26 Javascript
jquery判断单选按钮radio是否选中的方法
2015/05/05 Javascript
JavaScript类继承及实例化的方法
2015/07/25 Javascript
深入浅析JavaScript中数据共享和数据传递
2016/04/25 Javascript
基于jQuery制作小图标上下滑动特效
2017/01/18 Javascript
angular ng-click防止重复提交实例
2017/06/16 Javascript
用nodejs实现json和jsonp服务的方法
2017/08/25 NodeJs
vuejs数据超出单行显示更多,点击展开剩余数据实例
2019/05/05 Javascript
sharp.js安装过程中遇到的问题总结
2020/04/02 Javascript
VueJS实现用户管理系统
2020/05/29 Javascript
[01:46]2018完美盛典章节片——坚守
2018/12/17 DOTA
python3.3使用tkinter开发猜数字游戏示例
2014/03/14 Python
python实现斐波那契递归函数的方法
2014/09/08 Python
python3的输入方式及多组输入方法
2018/10/17 Python
python ChainMap 合并字典的实现步骤
2019/06/11 Python
Django文件上传与下载(FileFlid)
2019/10/06 Python
家得宝加拿大家装网上商店:The Home Depot加拿大
2016/08/27 全球购物
美国最大的网上冲印店:Shutterfly
2017/01/01 全球购物
Pure Collection美国官网:来自英国羊绒专家的奢华羊绒
2017/11/19 全球购物
印度尼西亚最大的电商平台:Tokopedia(印尼版淘宝)
2017/12/02 全球购物
护理毕业生自我鉴定
2014/02/11 职场文书
初中作文评语大全
2014/04/23 职场文书
中学生社会实践教育活动总结
2015/05/06 职场文书
2015年中学体育教师工作总结
2015/10/23 职场文书
公司要求试用期员工提交“述职报告”,该怎么写?
2019/07/17 职场文书
共青团优秀团员申请书(范文)
2019/08/15 职场文书
四十九个javascript小知识实用技巧
2021/11/20 Javascript
从零开始在Centos7上部署SpringBoot项目
2022/04/07 Servers
Tomcat弱口令复现及利用
2022/05/06 Servers