toFixed方法的bug

最近在工做過程當中碰到一個隱藏的bug,經調試發現居然是toFixed函數不可靠的結果引發的。後端同窗在處理價格比較的時候,用foFixed進行價格的四捨五入以後,居然發現比較的結果有問題;javascript

你們都知道,Number類型的變量有個toFixed方法,該方法將Number四捨五入爲指定小數位數的數字,以字符串返回。java

IE:git

0.6 .toFixed(0); // 0
1.6 .toFixed(0); // 2

Chrome:後端

0.6 .toFixed(0); // 1
1.6 .toFixed(0); // 2

另外還發現,就算是同在Chrome裏,四捨五入也不靠譜:函數

( 0.035 ).toFixed( 2 ); // 0.04
( 0.045 ).toFixed( 2 ); // 0.04

此次IE卻是靠譜了:調試

( 0.035 ).toFixed( 2 ); // 0.04
( 0.045 ).toFixed( 2 ); // 0.05

結論 :toFixed()函數靠不住,若是有須要精確控制的狀況,仍是本身寫個方法比較好。好比:code

function toFixed(number, decimal) {
	decimal = decimal || 0;
	var s = String(number);
	var decimalIndex = s.indexOf('.');
	if (decimalIndex < 0) {
		var fraction = '';
		for (var i = 0; i < decimal; i++) {
			fraction += '0';
		}
		return s + '.' + fraction;
	}
	var numDigits = s.length - 1 - decimalIndex;
	if (numDigits <= decimal) {
		var fraction = '';
		for (var i = 0; i < decimal - numDigits; i++) {
			fraction += '0';
		}
		return s + fraction;
	}
	var digits = s.split('');
	var pos = decimalIndex + decimal;
	var roundDigit = digits[pos + 1];
	if (roundDigit > 4) {
		//跳太小數點
		if (pos == decimalIndex) {
			--pos;
		}
		digits[pos] = Number(digits[pos] || 0) + 1;
		//循環進位
		while (digits[pos] == 10) {
			digits[pos] = 0;
			--pos;
			if (pos == decimalIndex) {
				--pos;
			}
			digits[pos] = Number(digits[pos] || 0) + 1;
		}
	}
	//避免包含末尾的.符號
	if (decimal == 0) {
		decimal--;
	}
	return digits.slice(0, decimalIndex + decimal + 1).join('');
}
var a = 19.02
var b = 209.01
// 結果
console.log(toFixed(a, 2)); //==> 19.02
console.log(toFixed(b, 2)); //==> 209.01
console.log(Number(toFixed(a, 2)) < Number(toFixed(b, 2))); //==> true
相關文章
相關標籤/搜索