0.1+0.2===0.3?

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.10.2转换成二进制看看:

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

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

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

最简单的解决方案:

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

IEEE 754 Floating-point

JS仅有Number这个数值类型,而 Number采用的时IEEE 754 64位双精度浮点数编码。而浮点数表示方式具有以下特点:

1. 浮点数可表示的值范围比同等位数的整数表示方式的值范围要大得多;

2. 浮点数无法精确表示其值范围内的所有数值,而有符号和无符号整数则是精确表示其值范围内的每个数值;

3. 浮点数只能精确表示 m*2e 的数值;

4. 当 biased-exponent 为 2e-1-1 时,浮点数能精确表示该范围内的各整数值;

5. 当 biased-exponent 不为 2e-1-1 时,浮点数不能精确表示该范围内的各整数值。

由于部分数值无法精确表示(存储),于是在运算统计后偏差会愈见明显。

参考文章

https://blog.csdn.net/forest_fire/article/details/50944339
https://www.cnblogs.com/fsjohnhuang/p/5115672.html

你可能感兴趣的:(0.1+0.2===0.3?)