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的对话框详解与参数
Mar 08 Javascript
js实现字符串的16进制编码不加密
Apr 25 Javascript
jQuery中fadeOut()方法用法实例
Dec 24 Javascript
js实现防止被iframe的方法
Jul 03 Javascript
JS实现漂亮的淡蓝色滑动门效果代码
Sep 23 Javascript
详解Javascript中的Object对象
Feb 28 Javascript
js多功能分页组件layPage使用方法详解
May 19 Javascript
详解Node.js项目APM监控之New Relic
May 12 Javascript
使用puppeteer破解极验的滑动验证码
Feb 24 Javascript
微信小程序swiper禁止用户手动滑动代码实例
Aug 23 Javascript
vue实现直播间点赞飘心效果的示例代码
Sep 20 Javascript
Vue文本模糊匹配功能如何实现
Jul 30 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 解决旧系统 查出所有数据分页的类
2012/08/27 PHP
win平台安装配置Nginx+php+mysql 环境
2016/01/12 PHP
PHP QRCODE生成彩色二维码的方法
2016/05/19 PHP
php实现微信分享朋友链接功能
2019/02/18 PHP
PHP使用 Imagick 扩展实现图片合成,圆角处理功能示例
2019/09/09 PHP
小议javascript 设计模式 推荐
2009/10/28 Javascript
js模拟select下拉菜单控件的代码
2013/05/08 Javascript
JS实现兼容性好,自动置顶的淘宝悬浮工具栏效果
2015/09/18 Javascript
javascript中异常处理案例(推荐)
2016/10/03 Javascript
bootstrap提示标签、提示框实现代码
2016/12/28 Javascript
利用Vue.js+Node.js+MongoDB实现一个博客系统(附源码)
2017/04/24 Javascript
详解基于vue-cli配置移动端自适应
2018/01/13 Javascript
简单了解小程序+node梳理登陆流程
2019/06/24 Javascript
微信小程序开发中var that =this的用法详解
2020/01/18 Javascript
微信小程序图片右边加两行文字的代码
2020/04/23 Javascript
简单了解JavaScript弹窗实现代码
2020/05/07 Javascript
[02:14]完美“圣”典2016风云人物:xiao8专访
2016/12/01 DOTA
Python开发SQLite3数据库相关操作详解【连接,查询,插入,更新,删除,关闭等】
2017/07/27 Python
总结Python图形用户界面和游戏开发知识点
2019/05/22 Python
简单了解python的内存管理机制
2019/07/08 Python
pycharm如何实现跨目录调用文件
2020/02/28 Python
python GUI库图形界面开发之PyQt5复选框控件QCheckBox详细使用方法与实例
2020/02/28 Python
python爬虫爬取图片的简单代码
2021/01/18 Python
html5 touch事件实现触屏页面上下滑动(二)
2016/03/10 HTML / CSS
美国波西米亚风格服装品牌:Show Me Your Mumu
2018/01/05 全球购物
STAY JAPAN台湾:预订日本民宿
2018/07/22 全球购物
CHARLES & KEITH台湾官网:新加坡时尚品牌
2019/07/30 全球购物
Keds加拿大官网:购买帆布运动鞋和皮鞋
2019/09/26 全球购物
公司成立感言
2014/01/11 职场文书
毕业生自荐信如何写
2014/03/24 职场文书
销售队伍口号
2014/06/11 职场文书
2014年圣诞节寄语
2014/12/08 职场文书
2015年度合同管理工作总结
2015/05/22 职场文书
外科护士长工作总结
2015/08/12 职场文书
django上传文件的三种方式
2021/04/29 Python
MySQL分区以及建索引的方法总结
2022/04/13 MySQL