1 回答

TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超4個(gè)贊
JS浮點(diǎn)計(jì)算問(wèn)題
問(wèn)題
用js進(jìn)行浮點(diǎn)數(shù)計(jì)算,結(jié)果可能會(huì)“超出預(yù)期”,大部分計(jì)算結(jié)果還是對(duì)的,但是我們可不想在計(jì)算這么嚴(yán)謹(jǐn)?shù)氖虑樯线€有意外的驚喜。比如:
0.3 + 0.6 = 0.8999999999999999
0.3 - 0.2 = 0.09999999999999998
0.3 * 1.5 = 0.44999999999999996
0.3 / 0.1 = 2.9999999999999996
js中數(shù)字類型只有Number;
js的Number是IEEE 754標(biāo)準(zhǔn)的64-bits的雙精度數(shù)值
0.3轉(zhuǎn)換后為0.299999999999999988897769753748
0.2轉(zhuǎn)換后為0.200000000000000011102230246252
0.299999999999999988897769753748-0.200000000000000011102230246252=0.099999999999999977795539507496
看完這幾個(gè)計(jì)算結(jié)果,如果你沒(méi)用過(guò)js,你可能會(huì)有點(diǎn)崩潰。我只能說(shuō),這就是js的魅力所在。
分析
在這之前,你需要知道以下幾點(diǎn):
網(wǎng)上有很多關(guān)于此問(wèn)題的解釋,由于計(jì)算機(jī)是用二進(jìn)制來(lái)存儲(chǔ)和處理數(shù)字,不能精確表示浮點(diǎn)數(shù),而js中沒(méi)有相應(yīng)的封裝類來(lái)處理浮點(diǎn)數(shù)運(yùn)算,直接計(jì)算會(huì)導(dǎo)致運(yùn)算精度丟失。其實(shí)高級(jí)語(yǔ)言(c#,java)也存在此問(wèn)題,只不過(guò)它們自己內(nèi)部做了處理,把這種精度差異給屏蔽掉了。有些小數(shù)轉(zhuǎn)換為二進(jìn)制位數(shù)是無(wú)窮的(有循環(huán)),但是64位中小數(shù)最多只有52位,因此對(duì)于位數(shù)超過(guò)的相當(dāng)于被截取了,導(dǎo)致了精度的丟失。這個(gè)地址可以用來(lái)浮點(diǎn)數(shù)和IEEE 754標(biāo)準(zhǔn)的64-bits的互轉(zhuǎn)(背后是二進(jìn)制的轉(zhuǎn)換),用這個(gè)我們來(lái)驗(yàn)證下0.3-0.2。
這和js直接計(jì)算的結(jié)果0.09999999999999998想吻合。
添加回答
舉報(bào)