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 相关文章推荐
FLASH 广告之外的链接
Dec 16 Javascript
JavaScript原生对象之Date对象的属性和方法详解
Mar 13 Javascript
JavaScript使用shift方法移除素组第一个元素实例分析
Apr 06 Javascript
基于javascript实现简单的抽奖系统
Apr 15 Javascript
JavaScript中instanceof运算符的使用示例
Jun 08 Javascript
JavaScript定义数组的三种方法(new Array(),new Array('x','y')
Oct 04 Javascript
Angular.Js的自动化测试详解
Dec 09 Javascript
微信小程序 参数传递实例代码
Mar 20 Javascript
vue项目每30秒刷新1次接口的实现方法
Dec 04 Javascript
es6数组之扩展运算符操作实例分析
Apr 25 Javascript
JS中的变量作用域(console版)
Jul 18 Javascript
JavaScript 实现继承的几种方式
Feb 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
基于PHP与XML的PDF文档生成技术
2006/10/09 PHP
使用adodb lite解决问题
2006/12/31 PHP
php mysql索引问题
2008/06/07 PHP
PHP+jquery+ajax实现即时聊天功能实例
2014/12/23 PHP
php通过array_merge()函数合并关联和非关联数组的方法
2015/03/18 PHP
使用PHP生成二维码的方法汇总
2015/07/22 PHP
关于PhpStorm设置点击编辑文件自动定位源文件的实现方式
2020/12/30 PHP
js实现ASP分页函数 HTML分页函数
2006/09/22 Javascript
一种JavaScript的设计模式
2006/11/22 Javascript
玩转jQuery按钮 请告诉我你最喜欢哪些?
2012/01/08 Javascript
JavaScript高级程序设计(第3版)学习笔记4 js运算符和操作符
2012/10/11 Javascript
jQuery中选择器小问题(新人难免遇到)
2014/03/31 Javascript
JS运动框架之分享侧边栏动画实例
2015/03/03 Javascript
AngularJS实现表单手动验证和表单自动验证
2015/12/09 Javascript
JS图片左右无缝隙滚动的实现(兼容IE,Firefox 遵循W3C标准)
2016/09/23 Javascript
原生JS实现跑马灯效果
2017/02/20 Javascript
详解微信小程序 通过控制CSS实现view隐藏与显示
2017/05/24 Javascript
详解Vuejs2.0 如何利用proxyTable实现跨域请求
2017/08/03 Javascript
详解a标签添加onclick事件的几种方式
2019/03/29 Javascript
express如何解决ajax跨域访问session失效问题详解
2019/06/20 Javascript
Django中实现点击图片链接强制直接下载的方法
2015/05/14 Python
关于pip的安装,更新,卸载模块以及使用方法(详解)
2017/05/19 Python
Python subprocess模块详细解读
2018/01/29 Python
python自动化测试之如何解析excel文件
2019/06/27 Python
Python学习之time模块的基本使用
2021/01/17 Python
STAUD官方网站:洛杉矶独有的闲适风格
2019/04/11 全球购物
添柏岚英国官方网站:Timberland英国
2019/11/28 全球购物
应届生体育教师自荐信
2013/10/03 职场文书
自荐信的禁忌和要点
2013/10/15 职场文书
小学英语教学反思
2014/01/30 职场文书
商学院大学生求职的自我评价
2014/03/12 职场文书
一年级评语大全
2014/04/23 职场文书
班级课外活动总结
2014/07/09 职场文书
购房协议书范本(无房产证)
2014/10/07 职场文书
小学少先队工作总结2015
2015/05/26 职场文书
合作协议书格式范本
2016/03/21 职场文书