Javascript 浮點(diǎn)運(yùn)算的問(wèn)題分析與解決方法
十進(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上無(wú)法真正的表示 ‘1.1',而只能做到一定程度上的準(zhǔn)確,這是無(wú)法避免的精度丟失:
1.09999999999999999
在JavaScript中問(wèn)題還要復(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
解決
那如何來(lái)避免這類 1.0-0.9 != 0.1 的非bug型問(wèn)題發(fā)生呢?下面給出一種目前用的比較多的解決方案, 在判斷浮點(diǎn)運(yùn)算結(jié)果前對(duì)計(jì)算結(jié)果進(jìn)行精度縮小,因?yàn)樵诰瓤s小的過(guò)程總會(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
方法提煉
// 通過(guò)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

JS+HTML5本地存儲(chǔ)Localstorage實(shí)現(xiàn)注冊(cè)登錄及驗(yàn)證功能示例

JS?中的URLSearchParams?對(duì)象操作(以對(duì)象的形式上傳參數(shù)到url)

JS判斷輸入字符串長(zhǎng)度實(shí)例代碼(漢字算兩個(gè)字符,字母數(shù)字算一個(gè))

ES6中的class是如何實(shí)現(xiàn)的(附Babel編譯的ES5代碼詳解)

利用JavaScript實(shí)現(xiàn)靜態(tài)圖片局部流動(dòng)效果