2012-10-07 25 views
1

對於舍入小數(價格),我已經使用.toFixed(2)很長一段時間了。但我最近才發現Javascript不能「精確」地圍繞小數點。我有點震驚,甚至10.005不能正確地圓整到10.01。它剛剛下降到10.00。其他時候它確實圓了。我喜歡控制我的代碼,所以對我來說這是一個很大的禁忌。Javascript .toFixed()更精確的四捨五入替代?

而且由於我正在計算價格,因此我認爲我需要更多(100%)準確的四捨五入的數字,可能是四位十進制數。

是否有沒有簡單的方法在JavaScript中進行基本舍入,正確的方法是什麼?

更新:正如Felix Kling所建議的,將我的價格處理爲美分整數的方法也存在缺點(除了更多的代碼)?

+6

不要使用浮點值的錢小提琴。最簡單的(imo)解決方案是以美分(或使用任何貨幣)計算價格,並根據您的需求格式化價格(例如以美元和美分)。避免以這種方式舍入錯誤。 –

+0

In cents ??必須查找那個! – fishbaitfood

+1

順便說一下,你確定它是'10.005',沒有被正確舍入,而不是'10 * 1.0005'嗎? – raina77ow

回答

0

像10.005這樣的數字不能相應舍入的原因是,您實際上沒有數字10.005,您只有一個最接近可能的數字,可以使用雙精度浮點數表示變量。

你的實際數量可能有點像10.00499999999276253,那自然會變成10.00而不是10.01。

要處理貨幣值,您應該使用可以準確表示值的數據類型。由於Javascript中的數字總是浮點數,因此剩下的就是將數字表示爲文本,並編寫自己的函數來完成數學運算(或者找到已經完成的數據)。

+0

那麼使用BigDecimal或BigNumber,而不是將我的價格處理爲分?此外,10.00499999999276253四捨五入,仍然應爲10.01,因爲.0049應該變爲.005,這應導致正確的.01。或者我錯過了什麼? – fishbaitfood

+3

@fishbaitfood:這不是多麼圓潤的作品。如果我圍繞'0.4445',我希望得到'0'。根據你的規則,我得到'0.445',然後'0.45',然後'0.5',然後'1'。舍入多次不是一個好主意。 – Eric

+0

這是有道理的,但對於一個2個小數的價格數字,它似乎是正確的四捨五入...:/ – fishbaitfood

0

這應該爲你工作,這裏的發揮與它周圍http://jsfiddle.net/5ffyC/1/

function moneyRound(flt){ 
    var splitStr = flt.toString().split('.'), 
     whole = (flt * 100) | 0; 

    if (splitStr.length > 1 && splitStr[1].length > 2){ 
     return splitStr[1][2] > 4? (whole + 1)/100: whole/100; 
    } else { 
     return flt; 
    } 
}