在Javascript中舍入十进制数

时间:2016-01-12 09:07:19

标签: javascript

由于错误的浮点算术,每个javascript程序员都知道javascript Math.round()在很多情况下不能为十进制数生成正确的舍入。

大多数找到的解决方案都指出使用简单的原型扩展:

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中正确舍入十进制数?请参阅下面的解决方案(使用单元测试)。

1 个答案:

答案 0 :(得分: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()的推文,在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");
});