¿Cómo redondear un número en Javascript?

159

Quiero usar Javascript para redondear un número. Como el número es moneda, quiero que se redondee como en estos ejemplos (2 puntos decimales):

  • 192.168 => 192.20
  • 192.11 => 192.20
  • 192.21 => 192.30
  • 192.26 => 192.30
  • 192.20 => 192.20

¿Cómo lograr esto usando Javascript? La función Javascript incorporada redondeará el número según la lógica estándar (menos y más de 5 para redondear).

cyberfly
fuente

Respuestas:

313
/**
 * @param num The number to round
 * @param precision The number of decimal places to preserve
 */
function roundUp(num, precision) {
  precision = Math.pow(10, precision)
  return Math.ceil(num * precision) / precision
}

roundUp(192.168, 1) //=> 192.2
Andrew Marshall
fuente
2
@ AndrewMarshall, ¿cuál es el propósito de multiplicar y luego dividir por 10?
codecowboy
66
@codecowboy Si no lo haces, entonces ceil()te lo daremos 193, así que debemos asegurarnos de que toda la precisión que queremos mantener esté antes del punto decimal. Luego hacemos la operación inversa para restaurar el valor "original".
Andrew Marshall
1
Si obtiene algún número como 192.19999999999997, puede solicitarlo .toFixed(1)anum
flamer.ohr
44
Y para aquellos que se preguntan cómo redondear al número ENTERO más cercano, solo necesitan Math.ceil (). El resto es solo para tratar con decimales. ¡Para salvar a otros el tiempo que me tomó el cerebro llegar a eso!
Nigel B. Peck el
Esta solución tiene un error: Math.ceil (0.0159 * 1000000000) / precision. Obtendrá una fracción 0.015900001. Necesita agregar una validación de rango para precisión.
Frank
26

Poco tarde, pero puede crear una función de JavaScript reutilizable para este propósito:

// Arguments: number to round, number of decimal places
function roundNumber(rnum, rlength) { 
    var newnumber = Math.round(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
    return newnumber;
}

Llame a la función como

alert(roundNumber(192.168,2));
suryakiran
fuente
2
Esto funciona muy bien, pero el OP preguntó cómo redondear un número, por lo que Math.ceil debería usarse aquí en lugar de Math.round.
kloddant el
Esta respuesta es mejor que la respuesta aceptada si está buscando redondear correctamente a pesar del lugar decimal al que apunta. Ej: 1.054 -> 1.05 1.055 -> 1.06 SIN EMBARGO aquí hay un caso límite: 1.005 -> 1 1.006 -> 1.01 Y 1.015 -> 1.01 1.016 -> 1.02 Así que tenga cuidado.
Jay K
21

El redondeo normal funcionará con un pequeño ajuste:

Math.round(price * 10)/10

y si desea mantener un formato de moneda, puede usar el método de Número .toFixed()

(Math.round(price * 10)/10).toFixed(2)

Aunque esto lo convertirá en una cadena =)

Sábalo
fuente
Math.round (192.11 * 100) / 100 -> 192.11
krtek
1
El segundo no necesita redondeo, es más comoprice.toFixed(2)
Michael Krelin: hacker el
@ Krtek ooops, gracias por atrapar eso. Leí mal la pregunta. Respuesta actualizada
Shad
2
El OP preguntó cómo redondear un número, por lo que Math.ceil debería usarse aquí en lugar de Math.round.
kloddant
10

Muy cerca de la respuesta TheEye , pero cambio una pequeña cosa para que funcione:

var num = 192.16;
    
console.log(    Math.ceil(num * 10) / 10    );

Hoàng Long
fuente
2

El OP espera dos cosas:
A. redondear a las décimas más altas y
B. mostrar un cero en el lugar de las centésimas (una necesidad típica con moneda).

Cumplir ambos requisitos parecería necesitar un método separado para cada uno de los anteriores. Aquí hay un enfoque que se basa en la respuesta sugerida de suryakiran:

//Arguments: number to round, number of decimal places.

function roundPrice(rnum, rlength) {
    var newnumber = Math.ceil(rnum * Math.pow(10, rlength-1)) / Math.pow(10, rlength-1);
    var toTenths = newnumber.toFixed(rlength);
    return toTenths;
}

alert(roundPrice(678.91011,2)); // returns 679.00
alert(roundPrice(876.54321,2)); // returns 876.60

Nota importante: esta solución produce un resultado muy diferente con números negativos y exponenciales.

En aras de la comparación entre esta respuesta y dos que son muy similares, vea los siguientes 2 enfoques. El primero simplemente se redondea a la centésima más cercana de lo habitual, y el segundo simplemente se redondea a la centésima más cercana (más grande).

function roundNumber(rnum, rlength) { 
    var newnumber = Math.round(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
    return newnumber;
}

alert(roundNumber(678.91011,2)); // returns 678.91

function ceilNumber(rnum, rlength) { 
    var newnumber = Math.ceil(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
    return newnumber;
}

alert(ceilNumber(678.91011,2)); // returns 678.92
Kay V
fuente
2

ok, esto ha sido respondido, pero pensé que te gustaría ver mi respuesta que llama a la función math.pow () una vez. Supongo que me gusta mantener las cosas SECAS.

function roundIt(num, precision) {
    var rounder = Math.pow(10, precision);
    return (Math.round(num * rounder) / rounder).toFixed(precision)
};

De alguna manera lo pone todo junto. Reemplace Math.round () con Math.ceil () para redondear en lugar de redondear, que es lo que quería el OP.

John Grabauskas
fuente
1

esta función limita el decimal sin número redondo

function limitDecimal(num,decimal){
     return num.toString().substring(0, num.toString().indexOf('.')) + (num.toString().substr(num.toString().indexOf('.'), decimal+1));
}
Behnam Mohammadi
fuente
Como alternativa más corta: return ('' + num) .split ('.'). Shift ()
Roberto
gracias Roberto, este código funciona, pero elimina todos los decimales
Behnam Mohammadi
0

He estado usando la respuesta de @AndrewMarshall durante mucho tiempo, pero encontré algunos casos extremos. Las siguientes pruebas no pasan:

equals(roundUp(9.69545, 4), 9.6955);
equals(roundUp(37.760000000000005, 4), 37.76);
equals(roundUp(5.83333333, 4), 5.8333);

Esto es lo que ahora uso para que el redondeo se comporte correctamente:

// Closure
(function() {
  /**
   * Decimal adjustment of a number.
   *
   * @param {String}  type  The type of adjustment.
   * @param {Number}  value The number.
   * @param {Integer} exp   The exponent (the 10 logarithm of the adjustment base).
   * @returns {Number} The adjusted value.
   */
  function decimalAdjust(type, value, exp) {
    // If the exp is undefined or zero...
    if (typeof exp === 'undefined' || +exp === 0) {
      return Math[type](value);
    }
    value = +value;
    exp = +exp;
    // If the value is not a number or the exp is not an integer...
    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
      return NaN;
    }
    // If the value is negative...
    if (value < 0) {
      return -decimalAdjust(type, -value, exp);
    }
    // Shift
    value = value.toString().split('e');
    value = Math[type](+(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));
  }

  // Decimal round
  if (!Math.round10) {
    Math.round10 = function(value, exp) {
      return decimalAdjust('round', value, exp);
    };
  }
  // Decimal floor
  if (!Math.floor10) {
    Math.floor10 = function(value, exp) {
      return decimalAdjust('floor', value, exp);
    };
  }
  // Decimal ceil
  if (!Math.ceil10) {
    Math.ceil10 = function(value, exp) {
      return decimalAdjust('ceil', value, exp);
    };
  }
})();

// Round
Math.round10(55.55, -1);   // 55.6
Math.round10(55.549, -1);  // 55.5
Math.round10(55, 1);       // 60
Math.round10(54.9, 1);     // 50
Math.round10(-55.55, -1);  // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1);      // -50
Math.round10(-55.1, 1);    // -60
Math.round10(1.005, -2);   // 1.01 -- compare this with Math.round(1.005*100)/100 above
Math.round10(-1.005, -2);  // -1.01
// Floor
Math.floor10(55.59, -1);   // 55.5
Math.floor10(59, 1);       // 50
Math.floor10(-55.51, -1);  // -55.6
Math.floor10(-51, 1);      // -60
// Ceil
Math.ceil10(55.51, -1);    // 55.6
Math.ceil10(51, 1);        // 60
Math.ceil10(-55.59, -1);   // -55.5
Math.ceil10(-59, 1);       // -50

Fuente: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round

Nicolas BADIA
fuente
1
Sus casos de prueba parecen incorrectos. roundUp(37.760000000000005, 4)debería ser 37.7601y roundUp(5.83333333, 4)debería ser 5.8334. Estos dos (y el primero) son válidos para el fn que proporcioné.
Andrew Marshall
@ AndrewMarshall tiene una razón, sus valores esperados son incorrectos para los casos 2 y 3.
Amn
-3

parseInt siempre se redondea soo .....

console.log(parseInt(5.8)+1);

do parseInt () + 1

Omar
fuente