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代码
Apr 23 Javascript
iphone safari不支持position fixed的解决方法
May 04 Javascript
jquery.post用法之type设置问题
Feb 24 Javascript
js实现图片从左往右渐变切换效果的方法
Feb 06 Javascript
JavaScript如何实现组合列表框中元素移动效果
Mar 01 Javascript
前端js实现文件的断点续传 后端PHP文件接收
Oct 14 Javascript
js匿名函数使用&传参(实例)
Sep 08 Javascript
vue.js数据绑定操作详解
Apr 23 Javascript
深入理解es6块级作用域的使用
Mar 28 Javascript
了解javascript中let和var及const关键字的区别
May 24 Javascript
基于JS抓取某高校附近共享单车位置 使用web方式展示位置变化代码实例
Aug 27 Javascript
Node.js API详解之 module模块用法实例分析
May 13 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初学者写及时补给skype用户充话费的小程序
2008/11/02 PHP
ajax调用返回php接口返回json数据的方法(必看篇)
2017/05/05 PHP
javascript 定义初始化数组函数
2009/09/07 Javascript
javascript下高性能字符串连接StringBuffer类
2010/08/16 Javascript
javascript 事件绑定问题
2011/01/01 Javascript
jQuery实现鼠标经过时出现隐藏层文字链接的方法
2015/10/12 Javascript
BootStrap Validator对于隐藏域验证和程序赋值即时验证的问题浅析
2016/12/01 Javascript
jQuery实现单击按钮遮罩弹出对话框效果(1)
2017/02/20 Javascript
vue实现未登录跳转到登录页面的方法
2018/07/17 Javascript
vue如何安装使用Quill富文本编辑器
2018/09/21 Javascript
layui table数据修改的回显方法
2019/09/04 Javascript
浅谈Vue3.0新版API之composition-api入坑指南
2020/04/30 Javascript
Jquery使用each函数实现遍历及数组处理
2020/07/14 jQuery
[01:05:41]EG vs Optic Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
Python列表(list)常用操作方法小结
2015/02/02 Python
详解Python验证码识别
2016/01/25 Python
使用11行Python代码盗取了室友的U盘内容
2018/10/23 Python
详解Python下Flask-ApScheduler快速指南
2018/11/04 Python
Python解决线性代数问题之矩阵的初等变换方法
2018/12/12 Python
Python实现新型冠状病毒传播模型及预测代码实例
2020/02/05 Python
python如何调用字典的key
2020/05/25 Python
解决python运行启动报错问题
2020/06/01 Python
python的flask框架难学吗
2020/07/31 Python
通过实例解析python and和or使用方法
2020/11/14 Python
CAT鞋美国官网:CAT Footwear
2017/11/27 全球购物
MUGLER官方网站:蒂埃里·穆勒香水
2019/11/26 全球购物
Traffic People官网:女式花裙、上衣和连身裤
2020/10/12 全球购物
日本亚马逊官方网站:Amazon.co.jp
2020/04/14 全球购物
JAVA和C++区别都有哪些
2015/03/30 面试题
研究生毕业鉴定
2014/01/29 职场文书
幼儿园秋游感想
2014/03/12 职场文书
个人委托书范本
2014/04/02 职场文书
房产买卖委托公证书
2014/04/04 职场文书
社区戒毒工作方案
2014/06/04 职场文书
物业公司的岗位任命书
2014/06/06 职场文书
Python基础之变量的相关知识总结
2021/06/23 Python