在js中0.1+0.2!==0.3,一直知道這個問題是js中精度丟失的問題造成的,但是不知道是怎么丟失的,這個的運算過程又是怎樣的,下面就來具體看下這個計算過程是怎樣造成精度丟失的。
第一次精度丟失
首先了解在js中保存數(shù)字都是按照IEEE754標準來表示數(shù)字的,IEEE754是一種國際標準,用于二進制浮點數(shù)的表示,取舍的規(guī)則。所以將0.1和0.2轉(zhuǎn)化成二進制這里就造成了一次精度丟失。
先看一下0.1和0.2轉(zhuǎn)成為二進制是什么樣的。小數(shù)轉(zhuǎn)二進制是采用"乘2取整"的方式進行轉(zhuǎn)換的,
1. 0.1轉(zhuǎn)化為二進制為0.000110011001100(無限循環(huán))
2. 0.2轉(zhuǎn)化為二進制為0.00110011001100(無限循環(huán))
因為轉(zhuǎn)成二進制后是無限循環(huán)小數(shù),計算機在存儲的時候會存儲為一個近似值,所以在轉(zhuǎn)二進制這個過程中就造成了精度丟失。
第二次精度丟失
轉(zhuǎn)化為二進制的數(shù)字相加;
轉(zhuǎn)成二進制相加的過程,在IEEE754的標準中,浮點數(shù)要采用科學計數(shù)法計數(shù),0.1的二進制采用科學計數(shù)法表示為1.10011001100....×2^(-4),0.2的二進制采用科學計數(shù)法表示為1.10011001100....×2^(-3),為了進行二進制加法,需要將兩個數(shù)的指數(shù)部分對齊。為了使二者小數(shù)點對齊,所以0.1需要小數(shù)點需要向后移動一位,在這個過程中也會造成一次精度丟失,兩者相加的值為0.0100110011.....,同樣是一個無限循環(huán)小數(shù)。然后再將這個二進制小數(shù)轉(zhuǎn)成十進制。
總結(jié)
其實在相加的過程中轉(zhuǎn)成二進制,然后在相加,在這個過程中經(jīng)歷了兩次精度丟失的問題,最后得到的結(jié)果只是一個近似值。
?如何解決
1.先擴大相對應(yīng)倍數(shù),得到結(jié)果后在除以對應(yīng)的倍數(shù),這樣就可以得到正確的結(jié)果
2.使用toFixed()
代碼如下
注意使用toFixed是可以得到0.3的,但是運行結(jié)果還是false的原因是得到的結(jié)果是String類型的,而0.3是Number的,所以===為false。
console.log(0.1 + 0.2 === 0.3); //false
console.log((0.1 * 10 + 0.2 * 10) / 10 === 0.3); //true
console.log((0.1 + 0.2).toFixed(1) === 0.3); //false
