由于错误的浮点算术,每个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中正确舍入十进制数?请参阅下面的解决方案(使用单元测试)。
答案 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");
});