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 相关文章推荐
ajax 文件上传应用简单实现
Mar 03 Javascript
javascript removeChild 使用注意事项
Apr 11 Javascript
JavaScript 事件入门知识
Apr 13 Javascript
深入理解逻辑表达式的用法 与或非的用法
Jun 06 Javascript
类似于QQ的右滑删除效果的实现方法
Oct 16 Javascript
gulp加批处理(.bat)实现ng多应用一键自动化构建
Feb 16 Javascript
Vue.js bootstrap前端实现分页和排序
Mar 10 Javascript
微信小程序 input输入及动态设置按钮的实现
Oct 27 Javascript
js 判断一个数字是不是2的n次方幂的实例
Nov 26 Javascript
vue.js+ElementUI实现进度条提示密码强度效果
Jan 18 Javascript
vue axios封装httpjs,接口公用配置拦截操作
Aug 11 Javascript
如何在现代JavaScript中编写异步任务
Jan 31 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 header函数分析详解
2011/08/06 PHP
php cc攻击代码与防范方法
2012/10/18 PHP
PHP exif扩展方法开启详解
2014/07/28 PHP
php_imagick实现图片剪切、旋转、锐化、减色或增加特效的方法
2014/12/15 PHP
PHP 9 大缓存技术总结
2015/09/17 PHP
PHP sdk文档处理常用代码示例解析
2020/12/09 PHP
node.js中的querystring.escape方法使用说明
2014/12/10 Javascript
使用jQuery jqPlot插件绘制柱状图
2014/12/18 Javascript
谈谈我对JavaScript中typeof和instanceof的深入理解
2015/12/25 Javascript
javascript断点调试心得分享
2016/04/23 Javascript
基于JS如何实现类似QQ好友头像hover时显示资料卡的效果(推荐)
2016/06/09 Javascript
Web程序员必备的7个JavaScript函数
2016/06/14 Javascript
JS获取本周周一,周末及获取任意时间的周一周末功能示例
2017/02/09 Javascript
详解数组Array.sort()排序的方法
2020/05/09 Javascript
JS实现的随机排序功能算法示例
2017/06/09 Javascript
nodejs发送http请求时遇到404长时间未响应的解决方法
2017/12/10 NodeJs
vue cli 全面解析
2018/02/28 Javascript
浅谈node中的cluster集群
2018/06/02 Javascript
Node.js中你不可不精的Stream(流)
2018/06/08 Javascript
JavaScript实现点击出现图片并统计点击次数功能示例
2018/07/23 Javascript
Bootstrap table表格初始化表格数据的方法
2018/07/25 Javascript
Angular4.x Event (DOM事件和自定义事件详解)
2018/10/09 Javascript
JS实现的杨辉三角【帕斯卡三角形】算法示例
2019/02/26 Javascript
python基础入门详解(文件输入/输出 内建类型 字典操作使用方法)
2013/12/08 Python
用Python给文本创立向量空间模型的教程
2015/04/23 Python
Python调用系统底层API播放wav文件的方法
2017/08/11 Python
Python 25行代码实现的RSA算法详解
2018/04/10 Python
对Python的zip函数妙用,旋转矩阵详解
2018/12/13 Python
Python骚操作之动态定义函数
2019/03/26 Python
浅谈Python3中strip()、lstrip()、rstrip()用法详解
2019/04/29 Python
python实现支付宝转账接口
2019/05/07 Python
Python3 合并二叉树的实现
2019/09/30 Python
pytorch使用horovod多gpu训练的实现
2020/09/09 Python
客户经理竞聘演讲稿
2014/05/15 职场文书
党的生日活动方案
2014/08/15 职场文书
职位证明模板
2015/06/23 职场文书