Javascript 浮点运算精度问题分析与解决

 更新时间:2014年03月26日 11:46:11   作者:  
浮点数的精度问题不是JavaScript特有的,因为有些小数以二进制表示位数是无穷的
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

分析

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

相关文章

  • js实现漂浮回顶部按钮实例

    js实现漂浮回顶部按钮实例

    这篇文章主要介绍了js实现漂浮回顶部按钮的方法,实例分析了javascript实现返回顶部功能的样式与动态实现技巧,非常具有实用价值,需要的朋友可以参考下
    2015-05-05
  • input链接页面、打开新网页等等的具体实现

    input链接页面、打开新网页等等的具体实现

    input可以链接到某页、返回、打开新网页、打开无边框的新窗口等等,本文整理了一些,感兴趣的朋友可以参考下
    2013-12-12
  • js+canvas实现图片格式webp/png/jpeg在线转换

    js+canvas实现图片格式webp/png/jpeg在线转换

    这篇文章主要介绍了js+canvas实现图片格式webp/png/jpeg在线转换,需要的朋友可以参考下
    2020-08-08
  • JS高级技巧(简洁版)

    JS高级技巧(简洁版)

    由于在JS中,所有的函数都是对象,所以使用函数指针十分简单,也是这些东西使JS函数有趣且强大,这里特分享一下
    2018-07-07
  • 由?JavaScript?的?with?引发的探索

    由?JavaScript?的?with?引发的探索

    这篇文章主要介绍了由?JavaScript?的?with?引发的探索,js?的?with?是为对象访问提供命名空间式的访问方式,with?创建一个对象的命名空间,在这个命名空间内你可以直接访问对象的属性,而不需要通过对象来访问,下面一起来了解更多详细内容吧
    2022-01-01
  • 原生js实现自定义难度的扫雷游戏

    原生js实现自定义难度的扫雷游戏

    这篇文章主要为大家详细介绍了原生js实现自定义难度的扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-01-01
  • JS中绑定事件顺序(事件冒泡与事件捕获区别)

    JS中绑定事件顺序(事件冒泡与事件捕获区别)

    本文主要介绍了JS中绑定事件顺序(事件冒泡与事件捕获区别)。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • JavaScript Event学习第九章 鼠标事件

    JavaScript Event学习第九章 鼠标事件

    鼠标事件是到目前为止最重要的事件。在这一章我将介绍一些鼠标事件的最常见的问题和技巧。
    2010-02-02
  • 同步异步动态引入js文件的几种方法总结

    同步异步动态引入js文件的几种方法总结

    下面小编就为大家带来一篇同步异步动态引入js文件的几种方法总结。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • 详细总结Javascript中的焦点管理

    详细总结Javascript中的焦点管理

    相信大家都知道焦点作为javascript中的一个重要功能,基本上和页面交互都离不开焦点。但却少有人对焦点管理系统地做总结归纳。本文就javascript中的焦点管理作详细介绍,有需要的朋友们可以参考借鉴。
    2016-09-09

最新评论

?


http://www.vxiaotou.com