Javascript 浮點(diǎn)運(yùn)算精度問題分析與解決
分析
JavaScript 只有一種數(shù)字類型 Number ,而且在Javascript中所有的數(shù)字都是以IEEE-754標(biāo)準(zhǔn)格式表示的。 浮點(diǎn)數(shù)的精度問題不是JavaScript特有的,因?yàn)橛行┬?shù)以二進(jìn)制表示位數(shù)是無窮的:
十進(jìn)制 二進(jìn)制
0.1 0.0001 1001 1001 1001 ...
0.2 0.0011 0011 0011 0011 ...
0.3 0.0100 1100 1100 1100 ...
0.4 0.0110 0110 0110 0110 ...
0.5 0.1
0.6 0.1001 1001 1001 1001 ...
所以比如 1.1 ,其程序?qū)嶋H上無法真正的表示 ‘1.1',而只能做到一定程度上的準(zhǔn)確,這是無法避免的精度丟失:
1.09999999999999999
在JavaScript中問題還要復(fù)雜些,這里只給一些在Chrome中測(cè)試數(shù)據(jù):
輸入 輸出
1.0-0.9 == 0.1 False
1.0-0.8 == 0.2 False
1.0-0.7 == 0.3 False
1.0-0.6 == 0.4 True
1.0-0.5 == 0.5 True
1.0-0.4 == 0.6 True
1.0-0.3 == 0.7 True
1.0-0.2 == 0.8 True
1.0-0.1 == 0.9 True
解決
那如何來避免這類 1.0-0.9 != 0.1 的非bug型問題發(fā)生呢?下面給出一種目前用的比較多的解決方案, 在判斷浮點(diǎn)運(yùn)算結(jié)果前對(duì)計(jì)算結(jié)果進(jìn)行精度縮小,因?yàn)樵诰瓤s小的過程總會(huì)自動(dòng)四舍五入:
(1.0-0.9).toFixed(digits) // toFixed() 精度參數(shù)須在 0 與20 之間
parseFloat((1.0-0.9).toFixed(10)) === 0.1 // 結(jié)果為True
parseFloat((1.0-0.8).toFixed(10)) === 0.2 // 結(jié)果為True
parseFloat((1.0-0.7).toFixed(10)) === 0.3 // 結(jié)果為True
parseFloat((11.0-11.8).toFixed(10)) === -0.8 // 結(jié)果為True
方法提煉
// 通過isEqual工具方法判斷數(shù)值是否相等
function isEqual(number1, number2, digits){
digits = digits == undefined? 10: digits; // 默認(rèn)精度為10
return number1.toFixed(digits) === number2.toFixed(digits);
}
isEqual(1.0-0.7, 0.3); // return true
// 原生擴(kuò)展方式,更喜歡面向?qū)ο蟮娘L(fēng)格
Number.prototype.isEqual = function(number, digits){
digits = digits == undefined? 10: digits; // 默認(rèn)精度為10
return this.toFixed(digits) === number.toFixed(digits);
}
(1.0-0.7).isEqual(0.3); // return true
- JavaScript采用遞歸算法計(jì)算階乘實(shí)例
- 從階乘函數(shù)對(duì)比Javascript和C#的異同
- JavaScript使用遞歸和循環(huán)實(shí)現(xiàn)階乘的實(shí)例代碼
- JavaScript中常用的運(yùn)算符小結(jié)
- Js四則運(yùn)算函數(shù)代碼
- JS取模、取商及取整運(yùn)算方法示例
- JavaScript實(shí)現(xiàn)大數(shù)的運(yùn)算
- JS實(shí)現(xiàn)的加減乘除四則運(yùn)算計(jì)算器示例
- JavaScript中的數(shù)學(xué)運(yùn)算介紹
- 淺談JavaScript中運(yùn)算符的優(yōu)先級(jí)
- JS實(shí)現(xiàn)求5的階乘示例
相關(guān)文章
仿google adsense顏色選擇器代碼,從中易廣告聯(lián)盟程序提取
仿google adsense顏色選擇器代碼,從中易廣告聯(lián)盟程序提取...2007-11-11通過微信公眾平臺(tái)獲取公眾號(hào)文章的方法示例
這篇文章主要介紹了通過微信公眾平臺(tái)獲取公眾號(hào)文章的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12簡(jiǎn)單實(shí)現(xiàn)js無縫滾動(dòng)效果
這篇文章主要教大家如何簡(jiǎn)單實(shí)現(xiàn)js無縫滾動(dòng)效果,js輪播圖實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-025分鐘快速搭建vue3+ts+vite+pinia項(xiàng)目
本文主要介紹了5分鐘快速搭建vue3+ts+vite+pinia項(xiàng)目,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05JS實(shí)現(xiàn)將對(duì)象轉(zhuǎn)化為數(shù)組的方法分析
這篇文章主要介紹了JS實(shí)現(xiàn)將對(duì)象轉(zhuǎn)化為數(shù)組的方法,結(jié)合實(shí)例形式分析了javascript操作及轉(zhuǎn)換json數(shù)組相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-01-01js中如何對(duì)json數(shù)組進(jìn)行排序
這篇文章主要介紹了js中如何對(duì)json數(shù)組進(jìn)行排序的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04