Cómo redondear a máximo 2 decimales, si es necesario

Resuelto stinkycheeseman asked hace 12 años • 92 respuestas

Me gustaría redondear como máximo dos decimales, pero sólo si es necesario .

Aporte:

10
1.7777777
9.1

Producción:

10
1.78
9.1

¿Cómo puedo hacer esto en JavaScript?

stinkycheeseman avatar Aug 07 '12 00:08 stinkycheeseman
Aceptado

Usar Math.round():

Math.round(num * 100) / 100

O para ser más específico y garantizar que cosas como 1.005 se redondeen correctamente, use Number.EPSILON :

Math.round((num + Number.EPSILON) * 100) / 100
Brian Ustas avatar Aug 06 '2012 17:08 Brian Ustas

Si el valor es un tipo de texto:

parseFloat("123.456").toFixed(2);

Si el valor es un número:

var numb = 123.23454;
numb = numb.toFixed(2);

Existe la desventaja de que valores como 1,5 darán "1,50" como resultado. Una solución sugerida por @minitech:

var numb = 1.5;
numb = +numb.toFixed(2);
// Note the plus sign that drops any "extra" zeroes at the end.
// It changes the result (which is a string) into a number again (think "0 + foo"),
// which means that it uses only as many digits as necessary.

Parece que Math.roundes una mejor solución. ¡Pero no lo es! En algunos casos no se redondeará correctamente:

Math.round(1.005 * 100)/100 // Returns 1 instead of expected 1.01!

toFixed() tampoco se redondeará correctamente en algunos casos (probado en Chrome v.55.0.2883.87).

Ejemplos:

parseFloat("1.555").toFixed(2); // Returns 1.55 instead of 1.56.
parseFloat("1.5550").toFixed(2); // Returns 1.55 instead of 1.56.
// However, it will return correct result if you round 1.5551.
parseFloat("1.5551").toFixed(2); // Returns 1.56 as expected.

1.3555.toFixed(3) // Returns 1.355 instead of expected 1.356.
// However, it will return correct result if you round 1.35551.
1.35551.toFixed(2); // Returns 1.36 as expected.

Supongo que esto se debe a que 1,555 es en realidad algo así como flotante 1,55499994 detrás de escena.

La solución 1 es utilizar un script con el algoritmo de redondeo requerido, por ejemplo:

function roundNumber(num, scale) {
  if(!("" + num).includes("e")) {
    return +(Math.round(num + "e+" + scale)  + "e-" + scale);
  } else {
    var arr = ("" + num).split("e");
    var sig = ""
    if(+arr[1] + scale > 0) {
      sig = "+";
    }
    return +(Math.round(+arr[0] + "e" + sig + (+arr[1] + scale)) + "e-" + scale);
  }
}

También está en Plunker .

Nota: Esta no es una solución universal para todos. Existen varios algoritmos de redondeo diferentes. Su implementación puede ser diferente y depende de sus requisitos. Véase también Redondeo .

La solución 2 es evitar los cálculos frontales y extraer valores redondeados del servidor backend.

Otra posible solución, que tampoco es infalible.

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

En algunos casos, cuando redondeas un número como 1,3549999999999998, obtendrás un resultado incorrecto. Debería ser 1,35, pero el resultado es 1,36.

A Kunin avatar Oct 11 '2012 00:10 A Kunin