我想最多四舍五入两位小数,但只有在必要时。
输入:
10
1.7777777
9.1
输出:
10
1.78
9.1
如何在JavaScript中执行此操作?
我想最多四舍五入两位小数,但只有在必要时。
输入:
10
1.7777777
9.1
输出:
10
1.78
9.1
如何在JavaScript中执行此操作?
当前回答
我为自己编写了以下一组函数。也许这对你也有帮助。
function float_exponent(number) {
exponent = 1;
while (number < 1.0) {
exponent += 1
number *= 10
}
return exponent;
}
function format_float(number, extra_precision) {
precision = float_exponent(number) + (extra_precision || 0)
return number.toFixed(precision).split(/\.?0+$/)[0]
}
用法:
format_float(1.01); // 1
format_float(1.06); // 1.1
format_float(0.126); // 0.13
format_float(0.000189); // 0.00019
对于您的情况:
format_float(10, 1); // 10
format_float(9.1, 1); // 9.1
format_float(1.77777, 1); // 1.78
其他回答
如果您不想舍入,请使用以下函数。
function ConvertToDecimal(num) {
num = num.toString(); // If it's not already a String
num = num.slice(0, (num.indexOf(".")) + 3); // With 3 exposing the hundredths place
alert('M : ' + Number(num)); // If you need it back as a Number
}
这是我解决这个问题的方法:
function roundNumber(number, precision = 0) {
var num = number.toString().replace(",", "");
var integer, decimal, significantDigit;
if (num.indexOf(".") > 0 && num.substring(num.indexOf(".") + 1).length > precision && precision > 0) {
integer = parseInt(num).toString();
decimal = num.substring(num.indexOf(".") + 1);
significantDigit = Number(decimal.substr(precision, 1));
if (significantDigit >= 5) {
decimal = (Number(decimal.substr(0, precision)) + 1).toString();
return integer + "." + decimal;
} else {
decimal = (Number(decimal.substr(0, precision)) + 1).toString();
return integer + "." + decimal;
}
}
else if (num.indexOf(".") > 0) {
integer = parseInt(num).toString();
decimal = num.substring(num.indexOf(".") + 1);
significantDigit = num.substring(num.length - 1, 1);
if (significantDigit >= 5) {
decimal = (Number(decimal) + 1).toString();
return integer + "." + decimal;
} else {
return integer + "." + decimal;
}
}
return number;
}
与Brian Ustas建议的使用Math.round不同,我更喜欢Math.trunc方法来解决以下问题:
const twoDecimalRound = num => Math.round(num * 100) / 100;
const twoDecimalTrunc = num => Math.trunc(num * 100) / 100;
console.info(twoDecimalRound(79.996)); // Not desired output: 80;
console.info(twoDecimalTrunc(79.996)); // Desired output: 79.99;
您应该使用:
Math.round( num * 100 + Number.EPSILON ) / 100
似乎没有人知道数字EPSILON。
此外,值得注意的是,这并不像某些人所说的那样是JavaScript的怪异之处。
这就是浮点数在计算机中的工作方式。与99%的编程语言一样,JavaScript没有自制的浮点数;它依赖于CPU/FPU。计算机使用二进制,在二进制中,没有像0.1这样的数字,而只是二进制的近似值。为什么?出于同样的原因,1/3不能用十进制写:它的值是0.33333333……无穷大为三。
这里是Number.EPSILON。这个数字是1和双精度浮点数字中存在的下一个数字之间的差值。就是这样:在1和1+number.EPSILON之间没有数字。
编辑:
正如评论中所问的,让我们澄清一件事:添加Number.EPSILON仅当要舍入的值是算术运算的结果时才相关,因为它可以吞下一些浮点误差增量。
当值来自直接来源(例如:文字、用户输入或传感器)时,它不起作用。
编辑(2019):
像@maganap和一些人指出的那样,最好在相乘之前加上Number.EPSILON:
Math.round( ( num + Number.EPSILON ) * 100 ) / 100
编辑(2019年12月):
最近,我使用了一个类似于此的函数来比较epsilon感知的数字:
const ESPILON_RATE = 1 + Number.EPSILON ;
const ESPILON_ZERO = Number.MIN_VALUE ;
function epsilonEquals( a , b ) {
if ( Number.isNaN( a ) || Number.isNaN( b ) ) {
return false ;
}
if ( a === 0 || b === 0 ) {
return a <= b + EPSILON_ZERO && b <= a + EPSILON_ZERO ;
}
return a <= b * EPSILON_RATE && b <= a * EPSILON_RATE ;
}
我的用例是我多年来开发的断言+数据验证库。
事实上,在代码中,我使用的是ESPILON_RATE=1+4*数字.EPSILON和EPSILON_ZERO=4*数字.MIN_VALUE(四倍于EPSILON),因为我想要一个足够宽松的等式检查器来累积浮点错误。
到目前为止,它看起来很适合我。我希望这会有所帮助。
对这个答案稍作修改,似乎效果不错。
作用
function roundToStep(value, stepParam) {
var step = stepParam || 1.0;
var inv = 1.0 / step;
return Math.round(value * inv) / inv;
}
用法
roundToStep(2.55) = 3
roundToStep(2.55, 0.1) = 2.6
roundToStep(2.55, 0.01) = 2.55