本篇文章主要是对javascript避免数字计算精度偏差的方法进行了介绍,须要的朋友能够过来参考下,但愿对你们有所帮助。javascript
若是我问你 0.1 + 0.2 等于几?你可能会送我一个白眼,0.1 + 0.2 = 0.3 啊,那还用问吗?连幼儿园的小朋友都会回答这么小儿科的问题了。可是你知道吗,一样的问题放在编程语言中,或许就不是想象中那么简单的事儿了。java
不信?咱们能够作个试验。git
先来看一段 JS。编程
var num1 = 0.1; var num2 = 0.2; alert(num1+num2 === '0.3');
执行结果是 false。没错,当我第一次看到这段代码时,我也理所固然地觉得它是 true,可是执行结果让我大跌眼镜,是个人打开方式不对吗?非也非也。咱们再执行如下代码试试就知道结果为何是 false 了。编程语言
var num1 = 0.1; var num2 = 0.2; alert( num1+numB );
原来,0.1 + 0.2 = 0.30000000000000004。是否是很奇葩?其实对于浮点数的四则运算,几乎全部的编程语言都会有相似精度偏差的问题,只不过在 C++/C#/Java 这些语言中已经封装好了方法来避免精度的问题,spa
而 JavaScript 是一门弱类型的语言,从设计思想上就没有对浮点数有个严格的数据类型,因此精度偏差的问题就显得格外突出。下面就分析下为何会有这个精度偏差,以及怎样修复这个偏差。设计
首先,咱们要站在计算机的角度思考 0.1 + 0.2 这个看似小儿科的问题。咱们知道,能被计算机读懂的是二进制,而不是十进制,因此咱们先把 0.1 和 0.2 转换成二进制看看:code
0.1==》0.1.toString(2)==》0.0001100110011(无限循环..)orm
0.2==》0.2.toString(2)==》0.001100110011(无限循环..)blog
双精度浮点数的小数部分最多支持 52 位,因此二者相加以后获得这么一串 0.0100110011001100110011001100110011001100110011001100 因浮点数小数位的限制而截断的二进制数字,这时候,咱们再把它转换为十进制,就成了 0.30000000000000004。
原来如此,那怎么解决这个问题呢?我想要的结果就是 0.1 + 0.2 === 0.3 啊!!!
有种最简单的解决方案,就是给出明确的精度要求,在返回值的过程当中,计算机会自动四舍五入,
好比:
var num1 = 0.1; var num2 = 0.2; alert( parseFloat((num1 + num2).toFixed(2)) === 0.30 );
可是四舍五入明显不是一劳永逸的办法。
若是有一个方法能帮咱们解决这些浮点数的精度问题,那该多好!因此,咱们就本身写一个方法。
咱们来试试下面这个方法:
formatNum = function(f, digit) { var m = Math.pow(10, digit); return parseInt(f * m, 10) / m; }
var num1 = 0.1;
var num2 = 0.2;
alert(formatNum(num1 + num2, 1) === 0.3);
这个方法是什么意思呢?
为了不产生精度差别,咱们要把须要计算的数字乘以 10 的 n 次幂,换算成计算机可以精确识别的整数,而后再除以 10 的 n 次幂,大部分编程语言都是这样处理精度差别的,咱们就借用过来处理一下 JS 中的浮点数精度偏差。
因此若是下次再有人问你 0.1 + 0.2 等于几,你可要当心回答咯!!