javascript避免数字计算精度误差的方法详解

 更新时间:2014年03月05日 09:57:45   作者:  
本篇文章主要是对javascript避免数字计算精度误差的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助

如果我问你 0.1 + 0.2 等于几?你可能会送我一个白眼,0.1 + 0.2 = 0.3 啊,那还用问吗?连幼儿园的小朋友都会回答这么小儿科的问题了。但是你知道吗,同样的问题放在编程语言中,或许就不是想象中那么简单的事儿了。
不信?我们先来看一段 JS。

var numA = 0.1;
var numB = 0.2;
alert( (numA + numB) === 0.3 );

执行结果是 false。没错,当我第一次看到这段代码时,我也理所当然地以为它是 true,但是执行结果让我大跌眼镜,是我的打开方式不对吗?非也非也。我们再执行以下代码试试就知道结果为什么是 false 了。

var numA = 0.1;
var numB = 0.2;
alert( numA + numB );

原来,0.1 + 0.2 = 0.30000000000000004。是不是很奇葩?其实对于浮点数的四则运算,几乎所有的编程语言都会有类似精度误差的问题,只不过在 C++/C#/Java 这些语言中已经封装好了方法来避免精度的问题,而 JavaScript 是一门弱类型的语言,从设计思想上就没有对浮点数有个严格的数据类型,所以精度误差的问题就显得格外突出。下面就分析下为什么会有这个精度误差,以及怎样修复这个误差。

首先,我们要站在计算机的角度思考 0.1 + 0.2 这个看似小儿科的问题。我们知道,能被计算机读懂的是二进制,而不是十进制,所以我们先把 0.1 和 0.2 转换成二进制看看:

0.1 => 0.0001 1001 1001 1001…(无限循环)
0.2 => 0.0011 0011 0011 0011…(无限循环)

双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串 0.0100110011001100110011001100110011001100110011001100 因浮点数小数位的限制而截断的二进制数字,这时候,我们再把它转换为十进制,就成了 0.30000000000000004。

原来如此,那怎么解决这个问题呢?我想要的结果就是 0.1 + 0.2 === 0.3 啊!!!

有种最简单的解决方案,就是给出明确的精度要求,在返回值的过程中,计算机会自动四舍五入,比如:

var numA = 0.1;
var numB = 0.2;
alert( parseFloat((numA + numB).toFixed(2)) === 0.3 );

但是明显这不是一劳永逸的方法,如果有一个方法能帮我们解决这些浮点数的精度问题,那该多好。我们来试试下面这个方法:

Math.formatFloat = function(f, digit) {
    var m = Math.pow(10, digit);
    return parseInt(f * m, 10) / m;
}

var numA = 0.1;
var numB = 0.2;

alert(Math.formatFloat(numA + numB, 1) === 0.3);

这个方法是什么意思呢?为了避免产生精度差异,我们要把需要计算的数字乘以 10 的 n 次幂,换算成计算机能够精确识别的整数,然后再除以 10 的 n 次幂,大部分编程语言都是这样处理精度差异的,我们就借用过来处理一下 JS 中的浮点数精度误差。

如果下次再有人问你 0.1 + 0.2 等于几,你可要小心回答咯!!

相关文章

  • bootstrap输入框组代码分享

    bootstrap输入框组代码分享

    Bootstrap 支持的另一个特性,输入框组,输入框组扩展自表单控件.下面小编给大家介绍bootstrap输入框组的代码,非常不错具有参考借鉴价值,感兴趣的朋友一起学习吧
    2016-06-06
  • 关于验证码在IE中不刷新的快速解决方法

    关于验证码在IE中不刷新的快速解决方法

    下面小编就为大家带来一篇关于验证码在IE中不刷新的快速解决方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • BootStrap Tooltip插件源码解析

    BootStrap Tooltip插件源码解析

    这篇文章主要为大家详细解析了BootStrap的Tooltip插件源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • 基于JavaScript实现前端数据多条件筛选功能

    基于JavaScript实现前端数据多条件筛选功能

    这篇文章主要为大家详细介绍了基于JavaScript实现前端数据多条件筛选功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • 微信小程序实现展示评分结果功能

    微信小程序实现展示评分结果功能

    这篇文章主要为大家详细介绍了微信小程序实现展示评分结果功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • JavaScript保存并运算页面中数字类型变量的写法

    JavaScript保存并运算页面中数字类型变量的写法

    这篇文章主要介绍了JavaScript保存并运算页面中数字类型变量的写法,当你在页面中需要不停运算一个数字变量时非常有用,普通的写法不能正常运算,使用本文方法就可以,需要的朋友可以参考下
    2015-07-07
  • 复杂的javascript窗口分帧解析

    复杂的javascript窗口分帧解析

    这篇文章主要为大家详细解析了复杂的javascript窗口分帧,什么是窗口分帧,JavaScript中帧窗口之间的关系,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • Bootstrap警告(Alerts)的实现方法

    Bootstrap警告(Alerts)的实现方法

    这篇文章主要为大家详细介绍了Bootstrap警告(Alerts)的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • 解决layer.open弹出框不能获取input框的值为空的问题

    解决layer.open弹出框不能获取input框的值为空的问题

    今天小编就为大家分享一篇解决layer.open弹出框不能获取input框的值为空的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • JS控制下拉列表左右选择实例代码

    JS控制下拉列表左右选择实例代码

    在本篇内容中小编给各位分享的是关于如何使用JS控制下拉列表左右选择的实例代码,需要的朋友们可以参考下。
    2020-05-05

最新评论