Truncar el número a dos decimales sin redondear

195

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
fuente
3
Estoy tentado de preguntar, ¿por qué no quieres redondear? Parece incorrecto sin importar dónde ...
Camilo Martin
38
Es útil cuando se muestra moneda.
Richard Ye
@ mik01aj: cuando se visualiza la moneda, es más común truncar los valores calculados, en lugar de redondearlos. Por ejemplo, la mayoría de los formularios de impuestos en los EE. UU. Se truncan en lugar de redondear centavos fraccionales calculados. En ese caso, el valor truncado es el valor correcto.
Steven Byks
44
@CamiloMartin hay una gran diferencia entre una deuda de 1,49 billones de dólares y 1,0 billones de dólares.
Broda Noel
3
También hay una gran diferencia entre 1.49 billones y 1.50 billones de dólares. Eso es $ 100 millones.
Liga

Respuestas:

227

Convierta el número en una cadena, haga coincidir el número con 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>

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

Gumbo
fuente
22
+1 Eso debería resolver el problema de redondeo. Yo todavía enviar el resultado de lo anterior utilizando toFixed, sin embargo, así: (Math.floor(value * 100) / 100).toFixed(2). Como probablemente sepa, pueden ocurrir cosas extrañas de precisión con los valores de coma flotante (y en el otro lado del espectro, si el número es 15, suena como lo quiere el OP 15.00).
TJ Crowder
1
jeje, o si combinas ambos:Number((15.7784514000*100).toString().match(/^\d+/)/100);
skobaljic
27
Math.floor (value * 100) / 100 no funcionará si value = 4.27 en serio, pruébalo.
Dark Hippo
3
@DarkHippo Eso es porque 4.27 es en realidad 4.26999999999, Math.round es generalmente una mejor solución, aunque no es la respuesta a la pregunta original. De manera realista, dado que la salida es una cadena, esto se debe hacer mediante la manipulación de cadenas en lugar de una solución numérica con todas las debilidades de coma flotante.
BJury
3
... eso no suena bien. La conversión entre tipos bajo cualquier circunstancia parece indirecta e insegura. A menos que un programador realmente avanzado argumentara que "todos los tipos son solo secuencias" o algo así.
JackHasaKeyboard
66

Actualización 5 nov 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 coma flotante en javascript siempre tendrán casos extremos, la solución anterior será precisa la mayor parte del tiempo, lo que no es lo suficientemente bueno. Hay algunas soluciones para esto num.toPrecision, como BigDecimal.js y accounting.js . Sin embargo, creo que simplemente analizar la cadena será la más simple y siempre precisa.

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.


Antigua respuesta, no siempre precisa.

Roll su propia función toFixed:

function toFixed(num, fixed) {
    fixed = fixed || 0;
    fixed = Math.pow(10, fixed);
    return Math.floor(num * fixed) / fixed;
}
guya
fuente
77
toFixed (4.56, 2) = 4.55
cryss
2
Muchas de estas respuestas tienen una multiplicación dentro de una función Math.floor (). ¡Esto fallará para algunos números! La aritmética de coma flotante no es precisa y debe usar diferentes métodos.
Nico Westerdale el
1
function toFixedCustom (num, fixed) {var re = new RegExp ('^ -? \\ d + (?: \. \\ d {0,' + (fixed || -1) + '})?'); if (num.toString (). match (re)) {return num.toString (). match (re) [0]; }}
Ryan Augustine
1
La respuesta actualizada fallará para un número lo suficientemente grande o pequeño que javascript representaría en notación científica. toFixed(0.0000000052, 2)rinde '5.2'. Esto se puede solucionar usando el return num.toFixed(fixed+1).match(re)[0];Aviso que estoy usando para Fijar con un decimal encima del objetivo para evitar el redondeo, luego ejecutando su coincidencia de
expresiones
32

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;

ベ ン ノ ス ケ
fuente
55
Si no está forzando un decimal, es posible que desee agregar un condicional en caso de que encuentre números enteros. De esta manera: num = num.toString (); if (num.indexOf (".")> 0) {num = num.slice (0, (num.indexOf (".")) + 3)}; Número (num);
ベ ン ノ ス ケ
1
bueno si tiene decimales pero si es un entero fallará
Ruslan López
Si el número es 0.00000052, entonces será un error obtener 5.2e
Vasanth
1
@Vasanth Si el número es 0.00000052, devuelve "0.00". Tal vez la respuesta ha sido editada desde entonces
Drenai
Sí, falla en casos
extremos
18

Octubre de 2017

Solución general para truncar (sin redondear) un número al ené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
0.000000199 => 1.99 *

* Como se menciona en la nota, eso se debe a la conversión implícita de JavaScript en exponencial para "1.99e-7" 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)
SC1000
fuente
2
toFixedTrunc(0.000000199, 2) // 1.99
Maharramoff
1
@ShamkhalMaharramov: si abres la consola de desarrollo e ingresas 0.000000199, ¿qué obtienes? Obtienes 1.99e-7. Además, si ingresa 0.000000199.toString (), ¿qué obtiene? Obtiene "1.99e-7" Entonces, cuando pasa 0.000000199 a la función, termina trabajando en "1.99e-7" no "0.000000199" y "correctamente" devuelve "1.99". Ver ecma-international.org/ecma-262/6.0/…
SC1000
13

parseInt es más rápido que Math.floor

function floorFigure(figure, decimals){
    if (!decimals) decimals = 2;
    var d = Math.pow(10,decimals);
    return (parseInt(figure*d)/d).toFixed(decimals);
};

floorFigure(123.5999)    =>   "123.59"
floorFigure(123.5999, 3) =>   "123.599"
Martin Varmus
fuente
2
falla con 1234567.89
Ruslan López
¿Podrías elaborar López?
zardilior
3
floorFigure (4.56, 2) = 4.55
cryss
7
num = 19.66752
f = num.toFixed(3).slice(0,-1)
alert(f)

Esto devolverá 19.66

Alex Peng
fuente
55
(4.9999) .toFixed (3) .slice (0, -1) devuelve 5.00, el resultado esperado es 4.99.
Bruno Lemos
1
Recomiendo usar algo como .toFixed (6) .slice (0, -4) en su lugar.
Bruno Lemos
eso es perfecto, en mi caso funciona bien. por ejemplo, si quiero tener solo un número decimal, use num.toFixed (2) .slice (0, -1) (si num tiene 1.2356, devolverá 1.2)
Esteban Perez
7

Simple haz esto

number = parseInt(number * 100)/100;
Imran Pollob
fuente
44
parseInt (8.2 * 100) = 819
VPaul
5

Estas soluciones funcionan, pero me parecen innecesariamente complicadas. Personalmente, me gusta usar el operador de módulo para obtener el resto de una operación de división, y eliminar eso. Suponiendo que num = 15.7784514:

num-=num%.01;

Esto es equivalente a decir num = num - (num% .01).

jtrick
fuente
Eso es interesante Nijkokun, gracias por señalarlo. Nunca me he encontrado con problemas al usar esta técnica, pero claramente debería mirar más de cerca casos como este. Como alternativa, puede usar ((num * = 100) - (num% 1)) / 100 que resuelve este problema. La prioridad en mi caso es la velocidad de ejecución debido al volumen de cálculos al que estoy aplicando esto, y esta es la forma más rápida de lograr esto que he encontrado.
jtrick
1
El objetivo era evitar las búsquedas y conversiones de objetos y funciones requeridas en las otras soluciones ofrecidas. ¡Gracias por la respuesta!
jtrick
1
también falla con negativos como -5
Ruslan López
También estoy interesado en un redondeo rápido, ¿cómo haría que este código haga 1 decimal?
thednp
5

Las respuestas aquí no me ayudaron, seguían redondeando o dándome el decimal incorrecto.

mi solución convierte su decimal en una cadena, extrae los caracteres y luego lo devuelve todo como un número.

function Dec2(num) {
  num = String(num);
  if(num.indexOf('.') !== -1) {
    var numarr = num.split(".");
    if (numarr.length == 1) {
      return Number(num);
    }
    else {
      return Number(numarr[0]+"."+numarr[1].charAt(0)+numarr[1].charAt(1));
    }
  }
  else {
    return Number(num);
  }  
}

Dec2(99); // 99
Dec2(99.9999999); // 99.99
Dec2(99.35154); // 99.35
Dec2(99.8); // 99.8
Dec2(10265.985475); // 10265.98
David D
fuente
Dec2 (99) debería devolver 99.00
VPaul
5

Mi versión para números positivos:

function toFixed_norounding(n,p)
{
    var result = n.toFixed(p);
    return result <= n ? result: (result - Math.pow(0.1,p)).toFixed(p);
}

Rápido, bonito, obvio. (versión para números positivos)

Alfa y Omega
fuente
necesitaba un no redondeo para los valores flotantes (por ejemplo, dinero), con solo 1 decimal. La función anterior debe ser la "respuesta" de este tema, es excelente, funciona de maravilla. Saludos al autor y gracias. :)))
Adrian Tanase
Falló por valor negativo. -0.7752. Pruebe que toFixed_norounding(-0.7752,2)regrese en -0.78lugar de-0.77
Ling Loeng
4

El siguiente código funciona muy bien para mí:

num.toString().match(/.\*\\..{0,2}|.\*/)[0];
MISSIRIA
fuente
Agregaré el signo menos opcional para hacerlo perfecto -?;)
Ruslan López
3

Lo arreglé usando la siguiente manera simple:

var num = 15.7784514;
Math.floor(num*100)/100;

Los resultados serán 15.77

oms
fuente
No funciona con valores negativos: -15.7784514devoluciones-15.78
Clément Baconnier
3

Solo trunca los dígitos:

function truncDigits(inputNumber, digits) {
  const fact = 10 ** digits;
  return Math.floor(inputNumber * fact) / fact;
}
Aral Roca
fuente
3

Otra solución de línea única:

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

Utilicé 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 para mantener.

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

remidej
fuente
1
Esta es la mejor respuesta si no tiene que admitir IE11.
TJ.
2

Aquí estás. Una respuesta que muestra otra forma de resolver el problema:

// For the sake of simplicity, here is a complete function:
function truncate(numToBeTruncated, numOfDecimals) {
    var theNumber = numToBeTruncated.toString();
    var pointIndex = theNumber.indexOf('.');
    return +(theNumber.slice(0, pointIndex > -1 ? ++numOfDecimals + pointIndex : undefined));
}

Tenga en cuenta el uso de + antes de la expresión final. Eso es convertir nuestra cadena truncada y cortada de nuevo al tipo de número.

¡Espero eso ayude!

Jakub Barczyk
fuente
1
Me gusta la simplicidad de este enfoque, y creo que todas las soluciones que evitan el uso de las matemáticas son más apropiadas para resolver este problema. Entonces, el uso de slice (), etc., es la forma correcta de avanzar. La única ventaja de mi método es que procesará los números pasados ​​que son cadenas [rodeadas de comillas [simple / doble]]. Por alguna razón, la función anterior arrojó un error en FF, cuando lo hice: console.log ('truncate ("0.85156", 2)', truncate ("0.85156", 2));
Charles Robertson
2

truncar sin ceros

function toTrunc(value,n){  
    return Math.floor(value*Math.pow(10,n))/(Math.pow(10,n));
}

o

function toTrunc(value,n){
    x=(value.toString()+".0").split(".");
    return parseFloat(x[0]+"."+x[1].substr(0,n));
}

prueba:

toTrunc(17.4532,2)  //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1)   //1.4
toTrunc(.4,2)       //0.4

truncar con ceros

function toTruncFixed(value,n){
    return toTrunc(value,n).toFixed(n);
}

prueba:

toTrunc(17.4532,2)  //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1)   //1.4
toTrunc(.4,2)       //0.40
ShAkKiR
fuente
2

Esto funcionó bien para mí. Espero que también solucione sus problemas.

function toFixedNumber(number) {
    const spitedValues = String(number.toLocaleString()).split('.');
    let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
    decimalValue = decimalValue.concat('00').substr(0,2);

    return '$'+spitedValues[0] + '.' + decimalValue;
}

// 5.56789      ---->  $5.56
// 0.342        ---->  $0.34
// -10.3484534  ---->  $-10.34 
// 600          ---->  $600.00

function convertNumber(){
  var result = toFixedNumber(document.getElementById("valueText").value);
  document.getElementById("resultText").value = result;
}


function toFixedNumber(number) {
        const spitedValues = String(number.toLocaleString()).split('.');
        let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
        decimalValue = decimalValue.concat('00').substr(0,2);

        return '$'+spitedValues[0] + '.' + decimalValue;
}
<div>
  <input type="text" id="valueText" placeholder="Input value here..">
  <br>
  <button onclick="convertNumber()" >Convert</button>
  <br><hr>
  <input type="text" id="resultText" placeholder="result" readonly="true">
</div>

Sandaru
fuente
2

La siguiente es una manera fácil de hacerlo, pero es necesario asegurarse de que el parámetro cantidad se proporcione como una cadena.

function truncate(amountAsString, decimals = 2){
  var dotIndex = amountAsString.indexOf('.');
  var toTruncate = dotIndex !== -1  && ( amountAsString.length > dotIndex + decimals + 1);
  var approach = Math.pow(10, decimals);
  var amountToTruncate = toTruncate ? amountAsString.slice(0, dotIndex + decimals +1) : amountAsString;  
  return toTruncate
    ?  Math.floor(parseFloat(amountToTruncate) * approach ) / approach
    :  parseFloat(amountAsString);

}

console.log(truncate("7.99999")); //OUTPUT ==> 7.99
console.log(truncate("7.99999", 3)); //OUTPUT ==> 7.999
console.log(truncate("12.799999999999999")); //OUTPUT ==> 7.99
Felipe Santa
fuente
2

function formatLimitDecimals(value, decimals) {
  value = value.toString().split('.')

  if (value.length === 2) {
    return Number([value[0], value[1].slice(0, decimals)].join('.'))
  } else {
    return Number(value[0]);
  }
}

console.log(formatLimitDecimals(4.156, 2)); // 4.15
console.log(formatLimitDecimals(4.156, 8)); // 4.156
console.log(formatLimitDecimals(4.156, 0)); // 4

Ruben Morales Felix
fuente
1

Solía (num-0.05).toFixed(1)tener el segundo decimal en el suelo.

王景飞
fuente
1

Mi solución en mecanografiado (se puede portar fácilmente a JS):

/**
 * Returns the price with correct precision as a string
 *
 * @param   price The price in decimal to be formatted.
 * @param   decimalPlaces The number of decimal places to use
 * @return  string The price in Decimal formatting.
 */
type toDecimal = (price: number, decimalPlaces?: number) => string;
const toDecimalOdds: toDecimal = (
  price: number,
  decimalPlaces: number = 2,
): string => {
  const priceString: string = price.toString();
  const pointIndex: number = priceString.indexOf('.');

  // Return the integer part if decimalPlaces is 0
  if (decimalPlaces === 0) {
    return priceString.substr(0, pointIndex);
  }

  // Return value with 0s appended after decimal if the price is an integer
  if (pointIndex === -1) {
    const padZeroString: string = '0'.repeat(decimalPlaces);

    return `${priceString}.${padZeroString}`;
  }

  // If numbers after decimal are less than decimalPlaces, append with 0s
  const padZeroLen: number = priceString.length - pointIndex - 1;
  if (padZeroLen > 0 && padZeroLen < decimalPlaces) {
    const padZeroString: string = '0'.repeat(padZeroLen);

    return `${priceString}${padZeroString}`;
  }

  return priceString.substr(0, pointIndex + decimalPlaces + 1);
};

Casos de prueba:

  expect(filters.toDecimalOdds(3.14159)).toBe('3.14');
  expect(filters.toDecimalOdds(3.14159, 2)).toBe('3.14');
  expect(filters.toDecimalOdds(3.14159, 0)).toBe('3');
  expect(filters.toDecimalOdds(3.14159, 10)).toBe('3.1415900000');
  expect(filters.toDecimalOdds(8.2)).toBe('8.20');

¿Alguna mejora?

VPaul
fuente
0

Haga rodar su propia toFixedfunción: para valores positivos Math.floorfunciona bien.

function toFixed(num, fixed) {
    fixed = fixed || 0;
    fixed = Math.pow(10, fixed);
    return Math.floor(num * fixed) / fixed;
}

Para valores negativos Math.floores redondo de los valores. Entonces puedes usarMath.ceil en lugar.

Ejemplo,

Math.ceil(-15.778665 * 10000) / 10000 = -15.7786
Math.floor(-15.778665 * 10000) / 10000 = -15.7787 // wrong.
Boopathi Sakthivel
fuente
55
Muchas de estas respuestas tienen una multiplicación dentro de una función Math.floor (). ¡Esto fallará para algunos números! La aritmética de coma flotante no es precisa y debe usar diferentes métodos.
Nico Westerdale el
0

La segunda solución de Gumbo, con la expresión regular, funciona pero es lenta debido a la expresión regular. La primera solución de Gumbo falla en ciertas situaciones debido a la imprecisión en los números de coma flotante. Vea el JSFiddle para una demostración y un punto de referencia. La segunda solución toma alrededor de 1636 nanosegundos por llamada en mi sistema actual, CPU Intel Core i5-2500 a 3.30 GHz.

La solución que he escrito implica agregar una pequeña compensación para ocuparse de la imprecisión de coma flotante. Es básicamente instantáneo, es decir, del orden de nanosegundos. Registré 2 nanosegundos por llamada, pero los temporizadores de JavaScript no son muy precisos ni granulares. Aquí está el JS Fiddle y el código.

function toFixedWithoutRounding (value, precision)
{
    var factorError = Math.pow(10, 14);
    var factorTruncate = Math.pow(10, 14 - precision);
    var factorDecimal = Math.pow(10, precision);
    return Math.floor(Math.floor(value * factorError + 1) / factorTruncate) / factorDecimal;
}

var values = [1.1299999999, 1.13, 1.139999999, 1.14, 1.14000000001, 1.13 * 100];

for (var i = 0; i < values.length; i++)
{
    var value = values[i];
    console.log(value + " --> " + toFixedWithoutRounding(value, 2));
}

for (var i = 0; i < values.length; i++)
{
    var value = values[i];
    console.log(value + " --> " + toFixedWithoutRounding(value, 4));
}

console.log("type of result is " + typeof toFixedWithoutRounding(1.13 * 100 / 100, 2));

// Benchmark
var value = 1.13 * 100;
var startTime = new Date();
var numRun = 1000000;
var nanosecondsPerMilliseconds = 1000000;

for (var run = 0; run < numRun; run++)
    toFixedWithoutRounding(value, 2);

var endTime = new Date();
var timeDiffNs = nanosecondsPerMilliseconds * (endTime - startTime);
var timePerCallNs = timeDiffNs / numRun;
console.log("Time per call (nanoseconds): " + timePerCallNs);
Daniel Barbalace
fuente
0

Sobre la base de la respuesta de David D :

function NumberFormat(num,n) {
  var num = (arguments[0] != null) ? arguments[0] : 0;
  var n = (arguments[1] != null) ? arguments[1] : 2;
  if(num > 0){
    num = String(num);
    if(num.indexOf('.') !== -1) {
      var numarr = num.split(".");
      if (numarr.length > 1) {
        if(n > 0){
          var temp = numarr[0] + ".";
          for(var i = 0; i < n; i++){
            if(i < numarr[1].length){
              temp += numarr[1].charAt(i);
            }
          }
          num = Number(temp);
        }
      }
    }
  }
  return Number(num);
}

console.log('NumberFormat(123.85,2)',NumberFormat(123.85,2));
console.log('NumberFormat(123.851,2)',NumberFormat(123.851,2));
console.log('NumberFormat(0.85,2)',NumberFormat(0.85,2));
console.log('NumberFormat(0.851,2)',NumberFormat(0.851,2));
console.log('NumberFormat(0.85156,2)',NumberFormat(0.85156,2));
console.log('NumberFormat(0.85156,4)',NumberFormat(0.85156,4));
console.log('NumberFormat(0.85156,8)',NumberFormat(0.85156,8));
console.log('NumberFormat(".85156",2)',NumberFormat(".85156",2));
console.log('NumberFormat("0.85156",2)',NumberFormat("0.85156",2));
console.log('NumberFormat("1005.85156",2)',NumberFormat("1005.85156",2));
console.log('NumberFormat("0",2)',NumberFormat("0",2));
console.log('NumberFormat("",2)',NumberFormat("",2));
console.log('NumberFormat(85156,8)',NumberFormat(85156,8));
console.log('NumberFormat("85156",2)',NumberFormat("85156",2));
console.log('NumberFormat("85156.",2)',NumberFormat("85156.",2));

// NumberFormat(123.85,2) 123.85
// NumberFormat(123.851,2) 123.85
// NumberFormat(0.85,2) 0.85
// NumberFormat(0.851,2) 0.85
// NumberFormat(0.85156,2) 0.85
// NumberFormat(0.85156,4) 0.8515
// NumberFormat(0.85156,8) 0.85156
// NumberFormat(".85156",2) 0.85
// NumberFormat("0.85156",2) 0.85
// NumberFormat("1005.85156",2) 1005.85
// NumberFormat("0",2) 0
// NumberFormat("",2) 0
// NumberFormat(85156,8) 85156
// NumberFormat("85156",2) 85156
// NumberFormat("85156.",2) 85156
Charles Robertson
fuente
0

Es más confiable obtener dos puntos flotantes sin redondear.

Respuesta de referencia

var number = 10.5859;
var fixed2FloatPoints = parseInt(number * 100) / 100;
console.log(fixed2FloatPoints);

Gracias !

Jaydeep Mor
fuente
0

Ya hay alguna respuesta adecuada con expresión regular y cálculo aritmético, también puede intentar esto

function myFunction() {
    var str = 12.234556; 
    str = str.toString().split('.');
    var res = str[1].slice(0, 2);
    document.getElementById("demo").innerHTML = str[0]+'.'+res;
}

// output: 12.23
rey neo
fuente
0

Esto es lo que se hizo con una cuerda

export function withoutRange(number) {
  const str = String(number);
  const dotPosition = str.indexOf('.');
  if (dotPosition > 0) {
    const length = str.substring().length;
    const end = length > 3 ? 3 : length;
    return str.substring(0, dotPosition + end);
  }
  return str;
}
Kishan Vaghela
fuente
0

Todas estas respuestas parecen un poco complicadas. Simplemente restaría 0.5 de su número y usaría toFixed ().

Sean Mayes
fuente
¿Querías decir 0,005?
Luan Nguyen
0

La solución más eficiente (para 2 dígitos de fracción) es restar 0.005 antes de llamar toFixed()

function toFixed2( num ) { return (num-0.005).toFixed(2) }

Los números negativos también se redondearán hacia abajo (lejos de cero). El OP no dijo nada sobre números negativos.

Wiimm
fuente
0

Sé que ya hay pocos ejemplos de trabajo, pero creo que vale la pena proponer mi equivalente String.toFixed, algunos pueden encontrarlo útil.

Esa es mi alternativa toFixed, que no redondea los números, solo los trunca o agrega ceros de acuerdo con la precisión dada. Para un número extralargo, utiliza el redondeo incorporado JS cuando la precisión es demasiado larga. La función funciona para todos los números problemáticos que he encontrado en la pila.

function toFixedFixed(value, precision = 0) {
    let stringValue = isNaN(+value) ? '0' : String(+value);

    if (stringValue.indexOf('e') > -1 || stringValue === 'Infinity' || stringValue === '-Infinity') {
        throw new Error('To large number to be processed');
    }

    let [ beforePoint, afterPoint ] = stringValue.indexOf('.') > -1 ? stringValue.split('.') : [ stringValue, ''];

    // Force automatic rounding for some long real numbers that ends with 99X, by converting it to string, cutting off last digit, then adding extra nines and casting it on number again
    // e.g. 2.0199999999999996: +('2.019999999999999' + '9999') will give 2.02
    if (stringValue.length >= 17 && afterPoint.length > 2 && +afterPoint.substr(afterPoint.length - 3) > 995) {
        stringValue = String(+(stringValue.substr(0, afterPoint.length - 1) + '9'.repeat(stringValue.split('.').shift().length + 4)));
        [ beforePoint, afterPoint ] = String(stringValue).indexOf('.') > -1 ? stringValue.split('.') : [ stringValue, ''];
    }

    if (precision === 0) {
        return beforePoint;
    } else if (afterPoint.length > precision) {
        return `${beforePoint}.${afterPoint.substr(0, precision)}`;
    } else {
        return `${beforePoint}.${afterPoint}${'0'.repeat(precision - afterPoint.length)}`;
    }
}

Tenga en cuenta que la precisión puede no manejarse correctamente para números de longitud 18 y mayores, por ejemplo, Chrome de 64 bits lo redondeará o agregará "e +" / "e-" para mantener la longitud del número en 18.

Si desea realizar operaciones con números reales, es más seguro multiplicarlo Math.sqrt(10, precision)primero, hacer los cálculos y luego el resultado de la inmersión por el valor del multiplicador.

Ejemplo:

0.06 + 0.01es 0.06999999999999999, y cada función de formato que no esté redondeando lo truncará 0.06para mayor precisión2 .

Pero si realiza la misma operación con multiplicador y divisor (0.06 * 100 + 0.01 * 100) / 100, obtendrá 0.07.

Es por eso que es tan importante usar ese multiplicador / divisor cuando se trata de números reales en JavaScript, especialmente cuando se calcula el dinero ...

MagyaDEV
fuente