在javascript中,當(dāng)我們做加法運(yùn)算的時候,會發(fā)現(xiàn),0.1 + 0.2 != 0.3 的情況捉偏,出現(xiàn)預(yù)期之外的結(jié)果是由什么造成的呢?
console.log(0.1 + 0.2);//0.30000000000000004
console.log(0.1 + 0.2 == 0.3);//false
javascript中的 number 類型就是浮點(diǎn)類型泻红,浮點(diǎn)數(shù)采用的是一種二進(jìn)制表示法夭禽,二進(jìn)制浮點(diǎn)數(shù)表示法并不能精確的表示類似0.1這樣的簡單數(shù)字,會存在舍入的誤差谊路。
在二進(jìn)制中讹躯,1/10(0.1)被表示為0.00110011001100110011……,0011是無限重復(fù)的缠劝,這是舍入誤差造成的潮梯,所以對于 0.1 + 0.2 這樣的運(yùn)算,操作數(shù)會被先轉(zhuǎn)成二進(jìn)制惨恭,然后在運(yùn)算:
0.1 => 0.0001 1001 1001 1001…(無限循環(huán))
0.2 => 0.0011 0011 0011 0011…(無限循環(huán))
所以兩者相加之后得到這么一串 0.0100110011001100110011001100110011001100...因浮點(diǎn)數(shù)小數(shù)位的限制而截斷的二進(jìn)制數(shù)字秉馏,這時候,再把它轉(zhuǎn)換為十進(jìn)制脱羡,就成了 0.30000000000000004萝究。
對于保證浮點(diǎn)數(shù)計算的正確性,有兩種常見方式锉罐。
一帆竹、先升冪在降冪
functionadd(num1, num2){
let r1, r2, m;
r1 = (''+num1).split('.')[1].length;
r2 = (''+num2).split('.')[1].length;
m = Math.pow(10,Math.max(r1,r2));
return(num1 * m + num2 * m) / m;
}
console.log(add(0.1,0.2));//0.3
console.log(add(0.15,0.2256));//0.3756
二、使用內(nèi)置的 toPrecision() 和 toFixed() 方法脓规,注意:方法的返回值字符串
functionadd(x, y) {
returnx.toPrecision() + y.toPrecision()
}
console.log(add(0.1,0.2));//"0.10.2"