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 相关文章推荐
jQuery 页面载入进度条实现代码
Feb 08 Javascript
jQuery 判断元素上是否绑定了事件
Oct 28 Javascript
ExtJS Window 最小化的一种方法
Nov 18 Javascript
jQuery $.get 的妙用 访问本地文本文件
Jul 12 Javascript
JavaScript字符串对象fromCharCode方法入门实例(用于把Unicode值转换为字符串)
Oct 17 Javascript
JS动态修改表格cellPadding和cellSpacing的方法
Mar 31 Javascript
js密码强度实时检测代码
Mar 02 Javascript
Javascript中arguments对象的详解与使用方法
Oct 04 Javascript
JS实现json对象数组按对象属性排序操作示例
May 18 Javascript
JavaScript实现简单计算器功能
Dec 19 Javascript
详解vue高级特性
Jun 09 Javascript
javascript的setTimeout()使用方法总结
Nov 20 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实现的在线人员函数库
2008/04/09 PHP
php session 检测和注销
2009/03/16 PHP
PHP中VC6、VC9、TS、NTS版本的区别与用法详解
2013/10/26 PHP
PHP使用get_headers函数判断远程文件是否存在的方法
2014/11/28 PHP
javascript中的作用域scope介绍
2010/12/28 Javascript
JS+CSS实现大气清新的滑动菜单效果代码
2015/10/22 Javascript
Javascript中的arguments对象
2016/06/20 Javascript
JS仿百度自动下拉框模糊匹配提示
2016/07/25 Javascript
AngularJS基础 ng-if 指令用法
2016/08/01 Javascript
jQuery实现的兼容性浮动层示例
2016/08/02 Javascript
JS+HTML5实现图片在线预览功能
2017/07/22 Javascript
Vue文件配置全局变量的实例
2018/09/06 Javascript
vue-cli的工程模板与构建工具详解
2018/09/27 Javascript
vue实现分环境打包步骤(给不同的环境配置相对应的打包命令)
2019/06/04 Javascript
使用webpack搭建pixi.js开发环境
2020/02/12 Javascript
结合axios对项目中的api请求进行封装操作
2020/09/21 Javascript
python实现ipsec开权限实例
2014/11/11 Python
python中引用与复制用法实例分析
2015/06/04 Python
Python中asyncio与aiohttp入门教程
2018/10/16 Python
pandas通过loc生成新的列方法
2018/11/28 Python
解决python中使用PYQT时中文乱码问题
2019/06/17 Python
解决py2exe打包后,总是多显示一个DOS黑色窗口的问题
2019/06/21 Python
python使用paramiko模块通过ssh2协议对交换机进行配置的方法
2019/07/25 Python
flask/django 动态查询表结构相同表名不同数据的Model实现方法
2019/08/29 Python
python numpy存取文件的方式
2020/04/01 Python
Python 面向对象之类class和对象基本用法示例
2020/02/02 Python
Python模拟FTP文件服务器的操作方法
2020/02/18 Python
Python之Django自动实现html代码(下拉框,数据选择)
2020/03/13 Python
简单了解Python字典copy与赋值的区别
2020/09/16 Python
Data URI scheme详解和使用实例及图片base64编码实现方法
2014/05/08 HTML / CSS
美国全球旅游运营商:Pacific Holidays
2018/06/18 全球购物
美国在线购买空气净化器、除湿器、加湿器网站:AllergyBuyersClub
2021/03/16 全球购物
C/C++程序员常见面试题一
2012/12/08 面试题
UDP协议功能
2013/01/06 面试题
第二批党的群众路线教育实践活动总结报告
2014/10/30 职场文书
2019年入党思想汇报格式与要求
2019/06/25 职场文书