[javascript] Math.round(num)vs num.toFixed(0)和瀏覽器不一致



Answers

我認為FF正在使用toFixed做正確的事情,因為下面的第10步說“如果有兩個這樣的n,請選擇更大的n。”

正如Grant Wagner所說:使用Math.ceil(x)Math.floor(x)代替x.toFixed()

以下所有內容均來自ECMAScript語言規範

15.7.4.5 Number.prototype.toFixed (fractionDigits)

返回一個字符串,其中包含以定點表示法表示的數字,小數點後面的fractionDigits數字。 如果fractionDigits未定義,則假定為0 。 具體來說,執行以下步驟:

  1. fToInteger(fractionDigits) 。 (如果未定義fractionDigits ,則此步驟將生成值0 )。
  2. 如果f < 0f > 20 ,則拋出RangeError異常。
  3. x為該數值。
  4. 如果xNaN ,則返回字符串"NaN"
  5. 我們是空字符串。
  6. 如果x ≥ 0 ,請轉到步驟9。
  7. 我們是"-"
  8. x = –x
  9. 如果x ≥ 10^21 ,則m = ToString(x)並轉到步驟20。
  10. n為整數,對於該整數, n ÷ 10^f – x的精確數學值盡可能接近零。 如果有兩個這樣的n ,則選擇較大的n
  11. 如果n = 0 ,則m為字符串"0" 。 否則,讓m為由n的十進製表示的數字組成的字符串(按順序,沒有前導零)。
  12. 如果f = 0 ,轉到步驟20。
  13. km的字符數。
  14. 如果k > f ,請轉到步驟18。
  15. z是由f+1–k出現的字符'0'組成的字符串。
  16. m是字符串zm的串聯。
  17. k = f + 1
  18. am的第一個k–f字符,讓bm的剩餘f字符。
  19. m是三個字符串a"."的串聯"." ,和b
  20. 返回字符串sm的串聯。

toFixed方法的length屬性為1

如果使用多個參數調用toFixed方法,則行為未定義(請參閱第15節)。

對於小於0或大於20fractionDigits值,允許實現擴展toFixed的行為。 在這種情況下, toFixed不一定會為這些值拋出RangeError

注意對於某些值, toFixed的輸出可能比toString更精確,因為toString僅打印足夠的有效數字以區分數字與相鄰數字值。 例如, (1000000000000000128).toString()返回"1000000000000000100" ,而(1000000000000000128).toFixed(0)返回"1000000000000000128"

Question

請考慮以下代碼:

for (var i=0;i<3;i++){
   var num = i + 0.50;
   var output = num + " " + Math.round(num) + " " + num.toFixed(0);
   alert(output);
}

在Opera 9.63中我得到:

0.5 1 0

1.5 2 2

2.5 3 2

在FF 3.03中我得到:

0.5 1 1

1.5 2 2

2.5 3 3

在IE 7中我得到:

0.5 1 0

1.5 2 2

2.5 3 3

注意粗體結果。 為什麼會出現這種不一致的情況? 這是否意味著應該避免使用toFixed(0) ? 將數字舍入到最接近的整數的正確方法是什麼?




toFixed()返回一個字符串值。 來自Javascript:The Definitive Guide

將數字轉換為包含小數位後指定位數的字符串。

Math.round()返回一個整數。

顯然,toFixed()似乎更多地用於賺錢,例如,

'$'+ 12.34253.toFixed(2)='$ 12.34'

很遺憾toFixed()似乎沒有正確地圓!




如果你得到不一致的答案,那肯定是這樣的。

我只能猜測你使用toFixed(0)的意圖是將十進制數轉換為整數,此時我推薦Math.floor()。 關於在這個問題這樣做的最佳方法,還有更多的討論。




Related