2016-01-12 63 views
0

每個JavaScript程序員都知道,在很多情況下,由於錯誤的浮點運算,JavaScript Math.round()不會對十進制數產生正確的舍入。使用Javascript對十進制數進行舍入

大部分找到的解決辦法告訴使用簡單的原型擴展:

Number.prototype.round = function (decimalPlaces) { 
    decimalPlaces = decimalPlaces || 0; 
    var power = Math.pow(10, decimalPlaces) 

    if (this > 0) { 
     return Math.round(this * power)/power; 
    } else { 
     return -(Math.round(Math.abs(this) * power)/power); 
    } 
}; 

但在(1.005).round(2)這一個失敗,它返回的1,而不是預期的1.01

那麼如何在JavaScript中正確地舍入十進制數字?參見下面的解決方案(使用單元測試)。

+0

我個人找到最適合用整數的方式工作,只用100或任何用於顯示的目的;) –

回答

0

正確的數字樣機擴展四捨五入十進制數字:

Number.prototype.round = function (decimalPlaces) { 
    decimalPlaces = decimalPlaces || 0; 

    var sign = (this < 0) ? -1 : 1, 
     exp = -decimalPlaces, 
     value; 

    // Shift 
    value = Math.abs(this).toString().split('e'); 
    value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp))); 

    // Shift back 
    value = value.toString().split('e'); 

    return (+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp))) * sign; 
}; 

此擴展的decimalAdjust()一個tweek,在the Mozilla Developer Network Documentation for Math.round()提到:

該解決方案QUnit測試:

test("Number.prototype.round", function() { 
    var value; 

    value = 0; 
    equal(value.round(0), 0, "Value: 0, decimals: 0, expected result: 0"); 

    value = 33.12; 
    equal(value.round(1), 33.1, "Value: 33.12, decimals: 1, expected result: 33.1"); 

    value = 33.15; 
    equal(value.round(1), 33.2, "Value: 33.15, decimals: 1, expected result: 33.2"); 

    value = 33.123; 
    equal(value.round(2), 33.12, "Value: 33.123, decimals: 2, expected result: 33.12"); 

    value = 1000033.125; 
    equal(value.round(2), 1000033.13, "Value: 1000033.125, decimals: 2, expected result: 1000033.13"); 

    value = 17.6949; 
    equal(value.round(2), 17.69, "Value: 17.6949, decimals: 2, expected result: 17.69"); 

    value = 33.1234; 
    equal(value.round(3), 33.123, "Value: 33.1234, decimals: 3, expected result: 33.123"); 

    value = 33.12359; 
    equal(value.round(3), 33.124, "Value: 33.12359, decimals: 3, expected result: 33.124"); 

    value = 33.12343; 
    equal(value.round(4), 33.1234, "Value: 33.12343, decimals: 4, expected result: 33.1234"); 

    value = 33.12346; 
    equal(value.round(4), 33.1235, "Value: 33.12346, decimals: 4, expected result: 33.1235"); 

    value = 33.123456789; 
    equal(value.round(5), 33.12346, "Value: 33.123456789, decimals: 5, expected result: 33.12346"); 

    value = 33.123456789; 
    equal(value.round(8), 33.12345679, "Value: 33.123456789, decimals: 8, expected result: 33.12345679"); 

    value = -123456.123456789; 
    equal(value.round(8), -123456.12345679, "Value: -123456.123456789, decimals: 8, expected result: -123456.12345679"); 

    value = -110.385; 
    equal(value.round(2), -110.39, "Value: -110.385, decimals: 2, expected result: -110.39"); 
}); 
+0

You shoul不要在JavaScript中擴展原生對象 - > http://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice –

+0

那麼,這個原型擴展可以很容易地重寫爲標準功能。 – petriq

+0

我知道。所以,也許你應該,然後;-) –