我想最多四舍五入两位小数,但只有在必要时。

输入:

10
1.7777777
9.1

输出:

10
1.78
9.1

如何在JavaScript中执行此操作?


当前回答

根据评论中已给出的答案,链接至http://jsfiddle.net/AsRqx/,下面的一个对我来说很好。

function C(num)
{
    return +(Math.round(num + "e+2") + "e-2");
}

function N(num, places)
{
    return +(Math.round(num + "e+" + places) + "e-" + places);
}

C(1.005);

N(1.005, 0);
N(1.005, 1); // Up to 1 decimal places
N(1.005, 2); // Up to 2 decimal places
N(1.005, 3); // Up to 3 decimal places

其他回答

使用Math.rround():

Math.round(num * 100) / 100

或者更具体地说,为了确保1.005这样的数字正确,请使用Number.EPSILON:

Math.round((num + Number.EPSILON) * 100) / 100

另一种方法是:

number = 16.6666666;
console.log(parseFloat(number.toFixed(2)));
"16.67"

number = 16.6;
console.log(parseFloat(number.toFixed(2)));
"16.6"

number = 16;
console.log(parseFloat(number.toFixed(2)));
"16"

.toFixed(2)返回一个正好有两个小数点的字符串,可以是尾随零,也可以不是尾随零。执行parseFloat()将消除那些尾随的零。

您应该使用:

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),因为我想要一个足够宽松的等式检查器来累积浮点错误。

到目前为止,它看起来很适合我。我希望这会有所帮助。

要不处理许多0,请使用以下变体:

Math.round(num * 1e2) / 1e2

虽然建议的答案通常是正确的,但没有考虑传入的数字的精度,这在原始问题中没有表示为要求,但在科学应用的情况下,这可能是一个要求,其中3不同于3.00(例如)。

事实上,建议的答案是3.001到3,而保持数字精度的信息应该是3.00。

下面是一个考虑到这一点的函数:

函数roundTo(值,十进制){让absValue=Math.abs(值);let int=数学地板(absValue).toString().length;let dec=absValue.toString().length-int;dec-=(Number.isIInteger(absValue)?0 : 1);返回值toPrecision(int+Math.min(dec,十进制));}