JavaScript 是一門弱類型的語言,從設(shè)計(jì)思想上就沒有對浮點(diǎn)數(shù)有個(gè)嚴(yán)格的數(shù)據(jù)類型,所以精度誤差的問題就顯得格外突出。下面就分析下為什么會有這個(gè)精度誤差,以及怎樣修復(fù)這個(gè)誤差。
首先,我們要站在計(jì)算機(jī)的角度思考 0.1 + 0.2 這個(gè)看似小兒科的問題。我們知道,能被計(jì)算機(jī)讀懂的是二進(jìn)制,而不是十進(jìn)制,所以我們先把 0.1 和 0.2 轉(zhuǎn)換成二進(jìn)制看看:
0.1 => 0.0001 1001 1001 1001…(無限循環(huán))
0.2 => 0.0011 0011 0011 0011…(無限循環(huán))
雙精度浮點(diǎn)數(shù)的小數(shù)部分最多支持 52 位,所以兩者相加之后得到這么一串 0.0100110011001100110011001100110011001100110011001100 因浮點(diǎn)數(shù)小數(shù)位的限制而截?cái)嗟亩M(jìn)制數(shù)字,這時(shí)候,我們再把它轉(zhuǎn)換為十進(jìn)制,就成了 0.30000000000000004。
原來如此,那怎么解決這個(gè)問題呢?我想要的結(jié)果就是 0.1 + 0.2 === 0.3 ?。。?!
有種最簡單的解決方案,就是給出明確的精度要求,在返回值的過程中,計(jì)算機(jī)會自動四舍五入,比如:
var numA = 0.1;
var numB = 0.2;
alert( parseFloat((numA + numB).toFixed(2)) === 0.3 );
乘法運(yùn)算中有這種,比如0.58*100,結(jié)果是57.99999999999999??梢杂肕ath.round()進(jìn)行處理,
------||-------
盡量避免對小數(shù)進(jìn)行操作,先處理成整數(shù)后在進(jìn)行操作,其結(jié)果會比較精確。