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中call和apply方法浅谈
Sep 27 Javascript
getAsDataURL在Firefox7.0下无法预览本地图片的解决方法
Nov 15 Javascript
JavaScript中获取高度和宽度函数总结
Oct 08 Javascript
jquery实现表格隔行换色效果
Nov 19 Javascript
基于javascript实现仿百度输入框自动匹配功能
Jan 03 Javascript
jquery实现跳到底部,回到顶部效果的简单实例(类似锚)
Jul 10 Javascript
js 声明数组和向数组中添加对象变量的简单实例
Jul 28 Javascript
JS实现的简单表单验证功能完整实例
Oct 14 Javascript
vue 1.x 交互实现仿百度下拉列表示例
Oct 21 Javascript
对Vue table 动态表格td可编辑的方法详解
Aug 28 Javascript
JS匿名函数内部this指向问题详析
May 10 Javascript
JS实现transform实现扇子效果
Jan 17 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
smarty实例教程
2006/11/19 PHP
php页面跳转代码 输入网址跳转到你定义的页面
2013/03/28 PHP
PHP has encountered a Stack overflow问题解决方法
2014/11/03 PHP
js中关于一个分号的崩溃示例
2013/11/11 Javascript
常见的原始JS选择器使用方法总结
2014/04/09 Javascript
9款2014最热门jQuery实用特效推荐
2014/12/07 Javascript
使用纯javascript实现放大镜效果
2015/03/18 Javascript
JavaScript的jQuery库中function的存在和参数问题
2015/08/13 Javascript
JS获取IMG图片高宽的简单实例
2016/05/17 Javascript
Bootstrap组件系列之福利篇几款好用的组件(推荐)
2016/06/23 Javascript
jQuery实现背景滑动菜单
2016/12/02 Javascript
基于jQuery的左滑出现删除按钮的示例
2017/08/29 jQuery
vue 1.x 交互实现仿百度下拉列表示例
2017/10/21 Javascript
Webpack path与publicPath的区别详解
2018/05/03 Javascript
原生JS实现简单的倒计时功能示例
2018/08/30 Javascript
详解利用nodejs对本地json文件进行增删改查
2019/09/20 NodeJs
微信小程序tabBar设置实例解析
2019/11/14 Javascript
Django静态资源URL STATIC_ROOT的配置方法
2014/11/08 Python
使用python 和 lint 删除项目无用资源的方法
2017/12/20 Python
Django中redis的使用方法(包括安装、配置、启动)
2018/02/21 Python
Django添加feeds功能的示例
2018/08/07 Python
python pandas cumsum求累计次数的用法
2019/07/29 Python
Python实现图片识别加翻译功能
2019/12/26 Python
使用pytorch完成kaggle猫狗图像识别方式
2020/01/10 Python
使用matplotlib动态刷新指定曲线实例
2020/04/23 Python
CSS3中的元素过渡属性transition示例详解
2016/11/30 HTML / CSS
Merrell美国官网:美国登山运动鞋品牌
2018/02/07 全球购物
常用UNIX 命令(Linux的常用命令)
2013/07/10 面试题
护士的岗位职责
2013/12/04 职场文书
体育教师求职信
2014/05/24 职场文书
模范班主任事迹材料
2014/12/17 职场文书
检讨书范文
2015/01/27 职场文书
第28个世界无烟日活动总结
2015/02/10 职场文书
2015年服务员个人工作总结
2015/05/27 职场文书
高考满分作文赏析(2篇)
2019/08/12 职场文书
图文详解matlab原始处理图像几何变换
2021/07/09 Python