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 相关文章推荐
JavaScript 事件参考手册
Dec 24 Javascript
学习ExtJS Column布局
Oct 08 Javascript
初窥JQuery-Jquery简介 入门了解篇
Nov 25 Javascript
深入理解JavaScript中的传值与传引用
Dec 09 Javascript
jquery.Ajax()方法调用Asp.Net后台的方法解析
Feb 13 Javascript
初识angular框架后的所思所想
Feb 19 Javascript
jQuery插件开发汇总
May 15 Javascript
AngularJs中 ng-repeat指令中实现含有自定义指令的动态html的方法
Jan 19 Javascript
React学习笔记之列表渲染示例详解
Aug 22 Javascript
详解基于DllPlugin和DllReferencePlugin的webpack构建优化
Jun 28 Javascript
vue两个组件间值的传递或修改方式
Jul 04 Javascript
Webpack设置环境变量的一些误区详解
Dec 19 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
网页游戏开发入门教程三(简单程序应用)
2009/11/02 PHP
PHP版网站缓存加快打开速度的方法分享
2012/06/03 PHP
基于preg_match_all采集后数据处理的一点心得笔记(编码转换和正则匹配)
2014/01/31 PHP
smarty模板引擎基础知识入门
2015/03/30 PHP
PHP实现过滤各种HTML标签
2015/05/17 PHP
PHP的Yii框架中过滤器相关的使用总结
2016/03/29 PHP
PHP函数import_request_variables()用法分析
2016/04/02 PHP
PHP对象克隆clone用法示例
2016/09/28 PHP
类似框架的js代码
2006/11/09 Javascript
asp javascript 实现关闭窗口时保存数据的办法
2007/11/24 Javascript
jquery imgareaselect 使用利用js与程序结合实现图片剪切
2009/07/30 Javascript
jquery.Jwin.js 基于jquery的弹出层插件代码
2012/05/23 Javascript
Javascript中的Array数组对象详谈
2014/03/03 Javascript
javascript中的this详解
2014/12/08 Javascript
jQuery中的基本选择器用法学习教程
2016/04/14 Javascript
Bootstrap每天必学之响应式导航、轮播图
2016/04/25 Javascript
JavaScript使用Range调色及透明度实例
2016/09/25 Javascript
js canvas实现简单的图像扩散效果
2020/06/28 Javascript
jQuery实现checkbox全选、反选及删除等操作的方法详解
2019/08/02 jQuery
vue动态循环出的多个select出现过的变为disabled(实例代码)
2019/11/10 Javascript
通过js实现压缩图片上传功能
2020/02/25 Javascript
js通过canvas生成图片缩略图
2020/10/02 Javascript
解决tensorflow1.x版本加载saver.restore目录报错的问题
2018/07/26 Python
python 美化输出信息的实例
2018/10/15 Python
django ORM之values和annotate使用详解
2020/05/19 Python
Python文件夹批处理操作代码实例
2020/07/21 Python
意大利在线药房:Farmacia Loreto Gallo
2019/08/09 全球购物
TobyDeals美国:在电子产品上获得最好的优惠和折扣
2019/08/11 全球购物
澳大利亚头发和美容产品购物网站:OZ Hair & Beauty
2020/03/27 全球购物
升旗仪式主持词
2014/03/19 职场文书
乡镇消防工作实施方案
2014/03/27 职场文书
企业法人代表任命书
2014/06/06 职场文书
安全生产工作汇报材料
2014/10/28 职场文书
会议营销主持词
2015/07/03 职场文书
学校标语口号大全
2015/12/26 职场文书
2016年企业安全生产月活动总结
2016/04/06 职场文书