Truncar número a dos decimales sin redondear

Resuelto tempid asked hace 14 años • 45 respuestas

Supongamos que tengo un valor de 15,7784514, quiero mostrarlo 15,77 sin redondeo.

var num = parseFloat(15.7784514);
document.write(num.toFixed(1)+"<br />");
document.write(num.toFixed(2)+"<br />");
document.write(num.toFixed(3)+"<br />");
document.write(num.toFixed(10));

Resultados en -

15.8
15.78
15.778
15.7784514000 

¿Cómo muestro 15,77?

tempid avatar Nov 16 '10 00:11 tempid
Aceptado

Convierta el número en una cadena, haga coincidir el número hasta el segundo decimal:

function calc(theform) {
    var num = theform.original.value, rounded = theform.rounded
    var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
    rounded.value = with2Decimals
}
<form onsubmit="return calc(this)">
Original number: <input name="original" type="text" onkeyup="calc(form)" onchange="calc(form)" />
<br />"Rounded" number: <input name="rounded" type="text" placeholder="readonly" readonly>
</form>
Expandir fragmento

El toFixedmétodo falla en algunos casos, a diferencia de toString, así que tenga mucho cuidado con él.

Gumbo avatar Nov 15 '2010 17:11 Gumbo

Actualización 5 de noviembre de 2016

Nueva respuesta, siempre precisa.

function toFixed(num, fixed) {
    var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?');
    return num.toString().match(re)[0];
}

Como las matemáticas de punto flotante en JavaScript siempre tendrán casos extremos, la solución anterior será precisa la mayor parte del tiempo, lo cual no es lo suficientemente bueno. Existen algunas soluciones para esto num.toPrecision, como BigDecimal.js y Accounting.js . Sin embargo, creo que simplemente analizar la cadena será lo más simple y siempre preciso.

Basando la actualización en la expresión regular bien escrita de la respuesta aceptada por @Gumbo, esta nueva función toFixed siempre funcionará como se esperaba.


Respuesta antigua, no siempre precisa.

Enrolla tu propia función toFixed:

function toFixed(num, fixed) {
    fixed = fixed || 0;
    fixed = Math.pow(10, fixed);
    return Math.floor(num * fixed) / fixed;
}
guya avatar Aug 05 '2012 17:08 guya

Otra solución de una sola línea:

number = Math.trunc(number*100)/100

Usé 100 porque quieres truncar al segundo dígito, pero una solución más flexible sería:

number = Math.trunc(number*Math.pow(10, digits))/Math.pow(10, digits)

donde dígitos es la cantidad de dígitos decimales que se conservarán.

Consulte las especificaciones de Math.trunc para obtener detalles y compatibilidad con el navegador.

remidej avatar Jan 04 '2018 16:01 remidej

Opté por escribir esto para eliminar manualmente el resto con cadenas para no tener que lidiar con los problemas matemáticos que vienen con los números:

num = num.toString(); //If it's not already a String
num = num.slice(0, (num.indexOf("."))+3); //With 3 exposing the hundredths place
Number(num); //If you need it back as a Number

Esto le dará "15,77" con num = 15,7784514;

ベンノスケ avatar Oct 10 '2012 01:10 ベンノスケ

Actualización (enero de 2021)

Dependiendo de su rango, un número en javascript podrá mostrarse en notación científica. Por ejemplo, si escribe 0.0000001 en la consola, es posible que lo vea como 1e-7, mientras que 0.000001 aparece sin cambios (0.000001). Si su aplicación funciona con un rango de números para los cuales no interviene la notación científica, puede simplemente ignorar esta actualización y usar la respuesta original a continuación.

Esta actualización consiste en agregar una función que verifica si el número está en formato científico y, de ser así, lo convierte a formato decimal. Aquí te propongo esta , pero puedes usar cualquier otra función que logre el mismo objetivo, según las necesidades de tu aplicación:

function toFixed(x) {
  if (Math.abs(x) < 1.0) {
    let e = parseInt(x.toString().split('e-')[1]);
    if (e) {
        x *= Math.pow(10,e-1);
        x = '0.' + (new Array(e)).join('0') + x.toString().substring(2);
    }
  } else {
    let e = parseInt(x.toString().split('+')[1]);
    if (e > 20) {
        e -= 20;
        x /= Math.pow(10,e);
        x += (new Array(e+1)).join('0');
    }
  }
  return x;
}

Ahora simplemente aplique esa función al parámetro (ese es el único cambio con respecto a la respuesta original):

function toFixedTrunc(x, n) {
      x = toFixed(x) 

      // From here on the code is the same than the original answer
      const v = (typeof x === 'string' ? x : x.toString()).split('.');
      if (n <= 0) return v[0];
      let f = v[1] || '';
      if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
      while (f.length < n) f += '0';
      return `${v[0]}.${f}`
    }

Esta versión actualizada aborda también un caso mencionado en un comentario:

toFixedTrunc(0.000000199, 2) => "0.00" 

Nuevamente, elija lo que mejor se adapte a las necesidades de su aplicación.

Respuesta original (octubre de 2017)

Solución general para truncar (sin redondear) un número al n-ésimo dígito decimal y convertirlo en una cadena con exactamente n dígitos decimales, para cualquier n≥0.
function toFixedTrunc(x, n) {
  const v = (typeof x === 'string' ? x : x.toString()).split('.');
  if (n <= 0) return v[0];
  let f = v[1] || '';
  if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
  while (f.length < n) f += '0';
  return `${v[0]}.${f}`
}

donde x puede ser un número (que se convierte en una cadena) o una cadena.

Aquí hay algunas pruebas para n=2 (incluida la solicitada por OP):

0           => 0.00
0.01        => 0.01
0.5839      => 0.58
0.999       => 0.99
1.01        => 1.01
2           => 2.00
2.551       => 2.55
2.99999     => 2.99
4.27        => 4.27
15.7784514  => 15.77
123.5999    => 123.59

Y para algunos otros valores de n:

15.001097   => 15.0010 (n=4)
0.000003298 => 0.0000032 (n=7)
0.000003298257899 => 0.000003298257 (n=12)
ingdc avatar Sep 12 '2017 08:09 ingdc