Javascript 浮点运算精度问题分析与解决


Posted in Javascript onMarch 26, 2014

分析

JavaScript 只有一种数字类型 Number ,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的。 浮点数的精度问题不是JavaScript特有的,因为有些小数以二进制表示位数是无穷的:

十进制           二进制
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+css在交互上的应用
Jul 18 Javascript
获取服务器传来的数据 用JS去空格的正则表达式
Mar 26 Javascript
原生JavaScript实现连连看游戏(附源码)
Nov 05 Javascript
ie浏览器使用js导出网页到excel并打印
Mar 11 Javascript
jQuery插件multiScroll实现全屏鼠标滚动切换页面特效
Apr 12 Javascript
详解Node.js实现301、302重定向服务
Apr 07 Javascript
JS简单判断滚动条的滚动方向实现方法
Apr 28 Javascript
Webpack执行命令参数详解
Jun 17 Javascript
JavaScript脚本语言是什么_动力节点Java学院整理
Jun 26 Javascript
JS中创建自定义类型的常用模式总结【工厂模式,构造函数模式,原型模式,动态原型模式等】
Jan 19 Javascript
javascript中floor使用方法总结
Feb 02 Javascript
详解vue路由
Aug 05 Javascript
javascript 3d 逐侦产品展示(核心精简)
Mar 26 #Javascript
Node.js模拟浏览器文件上传示例
Mar 26 #Javascript
JavaScript关闭当前页面(窗口)不带任何提示
Mar 26 #Javascript
JavaScript数字和字符串转换示例
Mar 26 #Javascript
jquery实现瀑布流效果分享
Mar 26 #Javascript
jquery实现效果比较好的table选中行颜色
Mar 25 #Javascript
Jquery对数组的操作技巧整理
Mar 25 #Javascript
You might like
php实现的简单数据库操作Model类
2016/11/16 PHP
php使用redis的有序集合zset实现延迟队列应用示例
2020/02/20 PHP
使用jquery实现图文切换效果另加特效
2013/01/20 Javascript
JavaScript的递归之递归与循环示例介绍
2013/08/05 Javascript
浅谈angularJS 作用域
2015/07/05 Javascript
基于BootStrap的Metronic框架实现页面链接收藏夹功能按钮移动收藏记录(使用Sortable进行拖动排序)
2016/08/29 Javascript
jQuery插件FusionCharts实现的3D帕累托图效果示例【附demo源码】
2017/03/25 jQuery
微信小程序开发图片拖拽实例详解
2017/05/05 Javascript
JS实现商品筛选功能
2020/08/19 Javascript
如何理解Vue的.sync修饰符的使用
2017/08/17 Javascript
webuploader分片上传的实现代码(前后端分离)
2018/09/10 Javascript
Nodejs中获取当前函数被调用的行数及文件名详解
2018/12/12 NodeJs
vue el-table实现行内编辑功能
2019/12/11 Javascript
Element实现表格嵌套、多个表格共用一个表头的方法
2020/05/09 Javascript
JavaScript数组常用的增删改查与其他属性详解
2020/10/13 Javascript
python自动化工具日志查询分析脚本代码实现
2013/11/26 Python
python多线程抓取天涯帖子内容示例
2014/04/03 Python
浅析Python中的序列化存储的方法
2015/04/28 Python
python基于隐马尔可夫模型实现中文拼音输入
2016/04/01 Python
Python中super函数的用法
2017/11/17 Python
python实现从pdf文件中提取文本,并自动翻译的方法
2018/11/28 Python
python的继承知识点总结
2018/12/10 Python
Tensorflow轻松实现XOR运算的方式
2020/02/03 Python
python中uuid模块实例浅析
2020/12/29 Python
Html5之title吸顶功能
2018/06/04 HTML / CSS
Missguided美国官网:英国时尚品牌
2018/01/18 全球购物
Made in Design英国:设计家具、照明、家庭装饰和花园家具
2019/09/24 全球购物
Java的类与C++的类有什么不同
2014/01/18 面试题
医院护士专业个人的求职信
2013/12/09 职场文书
网络信息管理员岗位职责
2014/01/05 职场文书
个人委托书范本汇总
2014/10/01 职场文书
幼儿园六一儿童节开幕词
2016/03/04 职场文书
职业规划从高考志愿专业选择开始
2019/08/08 职场文书
浅谈mysql执行过程以及顺序
2021/05/12 MySQL
十大最强水系宝可梦,最美宝可梦排第三,榜首大家最熟悉
2022/03/18 日漫
Python用any()函数检查字符串中的字母以及如何使用all()函数
2022/04/14 Python