Formatear un número con exactamente dos decimales en JavaScript

571

Tengo esta línea de código que redondea mis números a dos decimales. Pero obtengo números como este: 10.8, 2.4, etc. Esta no es mi idea de dos decimales, entonces, ¿cómo puedo mejorar lo siguiente?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);

Quiero números como 10.80, 2.40, etc. El uso de jQuery está bien para mí.

Abdominales
fuente
1
Su código es exactamente lo que estaba buscando (para reducir la precisión de flotación a 7 decimales para un archivo JSON más pequeño) Omitir Math.pow para velocidad val = Math.round (val * 10000000) / 10000000);
Pawel
A medida que la respuesta aceptada actualmente da sin duda un mal resultado para una amplia gama de valores gracias a agravar la imprecisión inherente a los números ( 0.565, 0.575, 1.005), puedo sugerir mirando de nuevo a esta respuesta , lo cual les ayuda corregir?
TJ Crowder
Tal vez desee incluir una biblioteca sprintf para JavaScript stackoverflow.com/questions/610406/…
Thilo
Después de redondear correctamente con el método de desplazamiento y redondeo de lugares decimales, puede usar el number.toFixed(x)método para convertirlo en una cadena con la cantidad requerida de ceros. Por ejemplo, redondear 1.34a 1.3con el método de navegador cruzado, luego agregar 1 cero y convertir a cadena con 1.3.toFixed(2)(para obtener "1.30")
Edward

Respuestas:

999

Para formatear un número usando notación de punto fijo, simplemente puede usar el método toFixed :

(10.8).toFixed(2); // "10.80"

var num = 2.4;
alert(num.toFixed(2)); // "2.40"

Tenga en cuenta que toFixed()devuelve una cadena.

IMPORTANTE : Tenga en cuenta que toFixed no se redondea el 90% del tiempo, devolverá el valor redondeado, pero en muchos casos, no funciona.

Por ejemplo:

2.005.toFixed(2) === "2.00"

ACTUALIZAR:

Hoy en día, puedes usar el Intl.NumberFormatconstructor. Es parte de la especificación de API de internacionalización ECMAScript (ECMA402). Tiene muy buena soporte de los navegadores , incluyendo incluso EI11, y es totalmente compatible con Node.js .

const formatter = new Intl.NumberFormat('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});

console.log(formatter.format(2.005)); // "2.01"
console.log(formatter.format(1.345)); // "1.35"

Alternativamente, puede usar el toLocaleStringmétodo, que internamente usará la IntlAPI:

const format = (num, decimals) => num.toLocaleString('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});


console.log(format(2.005)); // "2.01"
console.log(format(1.345)); // "1.35"

Esta API también le ofrece una amplia variedad de opciones para formatear, como miles de separadores, símbolos de moneda, etc.

CMS
fuente
17
No funciona de manera consistente en todos los navegadores, es decir, (0.09).toFixed(1);da 0.0 en IE8
ajbeaven
41
fijo no se redondea, puede hacerlo primero: (Math.round (0.09)). toFixed (1);
Rekans
32
@rekans: Esto está mal. Math.Round(0.09)volverá, 0así que esto siempre dará 0.0...
Chris
28
Esta es una mala idea en la mayoría de las situaciones, en algunos casos convierte el número en una cadena o un número de coma flotante.
Ash Blue
80
Tengo que estar de acuerdo con @AshBlue aquí ... esto solo es seguro para formatear la presentación de valores. Puede romper el código con más cálculos. De lo contrario, Math.round(value*100)/100funciona mejor para 2DP.
UpTheCreek
98

Este es un tema antiguo, pero aún tiene los mejores resultados de Google y las soluciones ofrecidas comparten el mismo problema de decimales de coma flotante. Aquí está la función (muy genérica) que uso, gracias a MDN :

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(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));
}

Como podemos ver, no tenemos estos problemas:

round(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27

Este carácter genérico también proporciona algunas cosas interesantes:

round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123

Ahora, para responder la pregunta del OP, uno tiene que escribir:

round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"

O, para una función más concisa, menos genérica:

function round2Fixed(value) {
  value = +value;

  if (isNaN(value))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));

  // Shift back
  value = value.toString().split('e');
  return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2);
}

Puedes llamarlo con:

round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"

Varios ejemplos y pruebas (¡gracias a @ tj-crowder !):

astorije
fuente
1
¿Cómo no hay una manera simple de hacer esto? ES6 al rescate?
zero_cool
Gracias por publicar el MDN polyfill. En la página MDN vinculada, el polyfill ya no está allí. Me pregunto por qué fue eliminado ...
King Holly
43

Por lo general, agrego esto a mi biblioteca personal, y después de algunas sugerencias y de usar la solución @TIMINeutron también, y hacer que se adapte a la longitud decimal, esta se adapta mejor:

function precise_round(num, decimals) {
   var t = Math.pow(10, decimals);   
   return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}

funcionará para las excepciones reportadas.

Miguel
fuente
2
precision_round (1.275,2) es 1.27?
allenhwkim
2
@Imre Cambie el valor de retorno a (Math.round (num * Math.pow (10, decimales)) / Math.pow (10, decimales)). ToFixed (2); y ya no tendrás ese problema.
dkroy
66
¿dónde declara "signo" y "dec" si su segunda función se selecciona como está, ¿no debería tenerlos como indefinidos?
Ady Ngom
2
He agregado un método alternativo para el signo de signo de missign en IE: gist.github.com/ArminVieweg/28647e735aa6efaba401
Armin
1
@Armin Tu solución también hace que funcione en Safari. La función original no funcionaba en Safari.
Dave
19

No sé por qué no puedo agregar un comentario a una respuesta anterior (tal vez estoy ciego, no sé), pero se me ocurrió una solución usando la respuesta de @Miguel:

function precise_round(num,decimals) {
   return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}

Y sus dos comentarios (de @bighostkim y @Imre):

  • Problema con precise_round(1.275,2)no devolver 1.28
  • Problema con precise_round(6,2)no devolver 6.00 (como él quería).

Mi solución final es la siguiente:

function precise_round(num,decimals) {
    var sign = num >= 0 ? 1 : -1;
    return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}

Como puede ver, tuve que agregar un poco de "corrección" (no es lo que es, pero como Math.round tiene pérdidas, puede verificarlo en jsfiddle.net; esta es la única forma en que supe cómo "arreglar" " eso). Agrega 0.001 al número ya rellenado, por lo que agrega 1tres 0s a la derecha del valor decimal. Por lo tanto, debe ser seguro de usar.

Después de eso agregué .toFixed(decimal)para generar siempre el número en el formato correcto (con la cantidad correcta de decimales).

Entonces eso es todo. Úsalo bien ;)

EDITAR: funcionalidad agregada a la "corrección" de números negativos.

tfrascaroli
fuente
2
La "corrección" es mayormente segura, pero por ejemplo, precise_round(1.27499,2)ahora también devuelve 1.28 ... No es Math.roundque sea con pérdida; la forma en que las computadoras almacenan internamente valores de punto flotante es. Básicamente, estás condenado a fallar con algunos valores antes de que los datos lleguen a tu función :)
Imre
@Imre, tienes toda la razón. Es por eso que explico qué está haciendo este 0.001 allí, en caso de que alguien quiera hacerlo "más preciso " o incluso eliminarlo (si tiene una supercomputadora con 2 Mbytes por flotador, lo que no creo que haya nadie aquí) ;)
tfrascaroli
1
En realidad, la especificación del lenguaje es bastante específica sobre el uso de 64 bits para valores numéricos, por lo que tener / usar una supercomputadora no cambiaría nada :)
Imre
para el 0.001 puede reemplazar agregando muchos ceros de acuerdo con la longitud de los decimales. entonces ..
Miguel
15

Una forma de estar 100% seguro de obtener un número con 2 decimales:

(Math.round(num*100)/100).toFixed(2)

Si esto causa errores de redondeo, puede usar lo siguiente como James ha explicado en su comentario:

(Math.round((num * 1000)/10)/100).toFixed(2)
Gerard de Visser
fuente
66
Esta es la mejor y más simple forma de hacerlo. Sin embargo, debido a las matemáticas de coma flotante, 1.275 * 100 = 127.49999999999999, lo que podría causar errores menores en el redondeo. Para solucionar esto, podemos multiplicar por 1000 y dividir por 10, como (1.275 * 1000) / 10 = 127.5. De la siguiente manera: var answer = (Math.round((num * 1000)/10)/100).toFixed(2);
James Gould
(Math.round ((1.015 * 1000) / 10) / 100) .toFixed (2) todavía da 1.01, ¿no debería ser 1.02?
gaurav5430
14

toFixed (n) proporciona n longitud después del punto decimal; toPrecision (x) proporciona x longitud total.

Use este método a continuación

// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
    // It will round to the tenths place
    num = 500.2349;
    result = num.toPrecision(4); // result will equal 500.2

Y si desea que el número sea fijo, use

result = num.toFixed(2);
Syed Umar Ahmed
fuente
no funciona bien ... para el número num = 50.2349 debe escribir a Precision (3) para obtener 50.2
Piotr Czyż
es solo un ejemplo, puede cambiarlo según sus necesidades @ PiotrCzyż
Syed Umar Ahmed
5

No encontré una solución precisa para este problema, así que creé la mía propia:

function inprecise_round(value, decPlaces) {
  return Math.round(value*Math.pow(10,decPlaces))/Math.pow(10,decPlaces);
}

function precise_round(value, decPlaces){
    var val = value * Math.pow(10, decPlaces);
    var fraction = (Math.round((val-parseInt(val))*10)/10);

    //this line is for consistency with .NET Decimal.Round behavior
    // -342.055 => -342.06
    if(fraction == -0.5) fraction = -0.6;

    val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
    return val;
}

Ejemplos:

function inprecise_round(value, decPlaces) {
  return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

function precise_round(value, decPlaces) {
  var val = value * Math.pow(10, decPlaces);
  var fraction = (Math.round((val - parseInt(val)) * 10) / 10);

  //this line is for consistency with .NET Decimal.Round behavior
  // -342.055 => -342.06
  if (fraction == -0.5) fraction = -0.6;

  val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
  return val;
}

// This may produce different results depending on the browser environment
console.log("342.055.toFixed(2)         :", 342.055.toFixed(2)); // 342.06 on Chrome & IE10

console.log("inprecise_round(342.055, 2):", inprecise_round(342.055, 2)); // 342.05
console.log("precise_round(342.055, 2)  :", precise_round(342.055, 2));   // 342.06
console.log("precise_round(-342.055, 2) :", precise_round(-342.055, 2));  // -342.06

console.log("inprecise_round(0.565, 2)  :", inprecise_round(0.565, 2));   // 0.56
console.log("precise_round(0.565, 2)    :", precise_round(0.565, 2));     // 0.57

Florian Ignaz Eßl
fuente
2
Gracias. Aquí hay una cancioncilla para probar esto: jsfiddle.net/lamarant/ySXuF . Estoy aplicando toFixed () al valor antes de devolverlo, que agrega el número correcto de ceros al final del valor devuelto.
lamarant
no funciona por valor = 0,004990845956707237 e inprecise_round (valor, 8) devuelve 0,00499085 pero debe devolver 0,00499084
MERT DOĞAN
3

@heridev y yo creamos una pequeña función en jQuery.

Puedes probar a continuación:

HTML

<input type="text" name="one" class="two-digits"><br>
<input type="text" name="two" class="two-digits">​

jQuery

// apply the two-digits behaviour to elements with 'two-digits' as their class
$( function() {
    $('.two-digits').keyup(function(){
        if($(this).val().indexOf('.')!=-1){         
            if($(this).val().split(".")[1].length > 2){                
                if( isNaN( parseFloat( this.value ) ) ) return;
                this.value = parseFloat(this.value).toFixed(2);
            }  
         }            
         return this; //for chaining
    });
});

DEMO EN LÍNEA:

http://jsfiddle.net/c4Wqn/

vicmaster
fuente
1
Puedo apreciar la contribución, aunque creo que agregar elementos DOM y jQuery en la mezcla parece estar fuera del alcance de la pregunta.
Chris Mayo
No debe escuchar el evento keyup, ya que se ve muy mal y no se activa cuando agrega algo con el script. Prefiero escuchar el inputevento. Esto no crea un efecto de parpadeo y también se dispara cuando accede al campo con JS
Le 'nton el
3

El problema con los valores de coma flotante es que están tratando de representar una cantidad infinita de valores (continuos) con una cantidad fija de bits. Entonces, naturalmente, debe haber alguna pérdida en el juego, y te van a morder algunos valores.

Cuando una computadora almacena 1.275 como un valor de coma flotante, en realidad no recordará si era 1.275 o 1.27499999999999993, o incluso 1.27500000000000002. Estos valores deberían dar resultados diferentes después de redondear a dos decimales, pero no lo harán, ya que para la computadora se ven exactamente iguales después del almacenamiento como valores de punto flotante, y no hay forma de restaurar los datos perdidos. Cualquier cálculo adicional solo acumulará tal imprecisión.

Por lo tanto, si la precisión es importante, debe evitar los valores de coma flotante desde el principio. Las opciones más simples son

  • usar una biblioteca dedicada
  • usar cadenas para almacenar y pasar los valores (acompañados de operaciones de cadena)
  • use números enteros (por ejemplo, podría pasar la cantidad de centésimas de su valor real, por ejemplo, la cantidad en centavos en lugar de la cantidad en dólares)

Por ejemplo, cuando se usan números enteros para almacenar el número de centésimos, la función para encontrar el valor real es bastante simple:

function descale(num, decimals) {
    var hasMinus = num < 0;
    var numString = Math.abs(num).toString();
    var precedingZeroes = '';
    for (var i = numString.length; i <= decimals; i++) {
        precedingZeroes += '0';
    }
    numString = precedingZeroes + numString;
    return (hasMinus ? '-' : '') 
        + numString.substr(0, numString.length-decimals) 
        + '.' 
        + numString.substr(numString.length-decimals);
}

alert(descale(127, 2));

Con cadenas, necesitará redondear, pero aún es manejable:

function precise_round(num, decimals) {
    var parts = num.split('.');
    var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
    var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
    var decimalPart = parts.length > 1 ? parts[1] : '';
    if (decimalPart.length > decimals) {
        var roundOffNumber = decimalPart.charAt(decimals);
        decimalPart = decimalPart.substr(0, decimals);
        if ('56789'.indexOf(roundOffNumber) > -1) {
            var numbers = integralPart + decimalPart;
            var i = numbers.length;
            var trailingZeroes = '';
            var justOneAndTrailingZeroes = true;
            do {
                i--;
                var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
                if (roundedNumber === '0') {
                    trailingZeroes += '0';
                } else {
                    numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
                    justOneAndTrailingZeroes = false;
                    break;
                }
            } while (i > 0);
            if (justOneAndTrailingZeroes) {
                numbers = '1' + trailingZeroes;
            }
            integralPart = numbers.substr(0, numbers.length - decimals);
            decimalPart = numbers.substr(numbers.length - decimals);
        }
    } else {
        for (var i = decimalPart.length; i < decimals; i++) {
            decimalPart += '0';
        }
    }
    return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}

alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));

Tenga en cuenta que esta función se redondea al más cercano, se vincula desde cero , mientras que IEEE 754 recomienda redondear al más cercano, incluso como el comportamiento predeterminado para las operaciones de punto flotante. Dichas modificaciones se dejan como ejercicio para el lector :)

Imre
fuente
3

Aquí hay uno simple

function roundFloat(num,dec){
    var d = 1;
    for (var i=0; i<dec; i++){
        d += "0";
    }
    return Math.round(num * d) / d;
}

Usar como alert(roundFloat(1.79209243929,4));

Jsfiddle

ow3n
fuente
2

Redondea tu valor decimal, luego úsalo toFixed(x)para tus dígitos esperados.

function parseDecimalRoundAndFixed(num,dec){
  var d =  Math.pow(10,dec);
  return (Math.round(num * d) / d).toFixed(dec);
}

Llamada

parseDecimalRoundAndFixed (10.800243929,4) => 10.80 parseDecimalRoundAndFixed (10.807243929,2) => 10.81

Hatcha
fuente
2

Redondear a la baja

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

Redondeo

function round_up(value, decPlaces) {
    return Math.ceil(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Ronda más cercana

function round_nearest(value, decPlaces) {
    return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Fusionado https://stackoverflow.com/a/7641824/1889449 y https://www.kirupa.com/html5/rounding_numbers_in_javascript.htm Gracias ellos.

MERT DOĞAN
fuente
2

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */

function RoundCorrect(num, precision = 2) {
	// half epsilon to correct edge cases.
	var c = 0.5 * Number.EPSILON * num;
//	var p = Math.pow(10, precision); //slow
	var p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing some +ve edge cases
console.log(RoundCorrect(1.005, 2));  // 1.01 correct
console.log(RoundCorrect(2.175, 2));  // 2.18 correct
console.log(RoundCorrect(5.015, 2));  // 5.02 correct

// testing some -ve edge cases
console.log(RoundCorrect(-1.005, 2));  // -1.01 correct
console.log(RoundCorrect(-2.175, 2));  // -2.18 correct
console.log(RoundCorrect(-5.015, 2));  // -5.02 correct

Amr Ali
fuente
2

Aquí está mi solución de 1 línea: Number((yourNumericValueHere).toFixed(2));

Esto es lo que pasa:

1) Primero, se aplica .toFixed(2)al número que desea redondear los lugares decimales. Tenga en cuenta que esto convertirá el valor en una cadena desde el número. Entonces, si está utilizando Typecript, arrojará un error como este:

"El tipo 'cadena' no se puede asignar al tipo 'número'"

2) Para recuperar el valor numérico o para convertir la cadena en un valor numérico, simplemente aplique la Number()función en ese llamado valor de 'cadena'.

Para aclarar, mira el siguiente ejemplo:

EJEMPLO: Tengo una cantidad que tiene hasta 5 dígitos en decimales y me gustaría acortarla hasta 2 decimales. Lo hago así:

var price = 0.26453;
var priceRounded = Number((price).toFixed(2));
console.log('Original Price: ' + price);
console.log('Price Rounded: ' + priceRounded);

Devner
fuente
1

Ponga lo siguiente en un alcance global:

Number.prototype.getDecimals = function ( decDigCount ) {
   return this.toFixed(decDigCount);
}

y luego intente :

var a = 56.23232323;
a.getDecimals(2); // will return 56.23

Actualizar

Tenga en cuenta que toFixed()solo puede funcionar para la cantidad de decimales, 0-20es decir, a.getDecimals(25)puede generar un error de JavaScript, por lo tanto, para adaptarse, puede agregar alguna verificación adicional, es decir

Number.prototype.getDecimals = function ( decDigCount ) {
   return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}
Kamran Ahmed
fuente
1
Number(((Math.random() * 100) + 1).toFixed(2))

esto devolverá un número aleatorio de 1 a 100 redondeado a 2 decimales.

Johnathan Ralls
fuente
1

Usando esta respuesta por referencia: https://stackoverflow.com/a/21029698/454827

Construyo una función para obtener números dinámicos de decimales:

function toDec(num, dec)
{
        if(typeof dec=='undefined' || dec<0)
                dec = 2;

        var tmp = dec + 1;
        for(var i=1; i<=tmp; i++)
                num = num * 10;

        num = num / 10;
        num = Math.round(num);
        for(var i=1; i<=dec; i++)
                num = num / 10;

        num = num.toFixed(dec);

        return num;
}

aquí ejemplo de trabajo: https://jsfiddle.net/wpxLduLc/

ZiTAL
fuente
1

parse = function (data) {
       data = Math.round(data*Math.pow(10,2))/Math.pow(10,2);
       if (data != null) {
            var lastone = data.toString().split('').pop();
            if (lastone != '.') {
                 data = parseFloat(data);
            }
       }
       return data;
  };

$('#result').html(parse(200)); // output 200
$('#result1').html(parse(200.1)); // output 200.1
$('#result2').html(parse(200.10)); // output 200.1
$('#result3').html(parse(200.109)); // output 200.11
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="result"></div>
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>

Vishnu T Asok
fuente
1

Con estos ejemplos, aún obtendrá un error cuando intente redondear el número 1.005, la solución es usar una biblioteca como Math.js o esta función:

function round(value: number, decimals: number) {
    return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}
David Webster
fuente
1

Obtuve algunas ideas de esta publicación hace unos meses, pero ninguna de las respuestas aquí, ni las respuestas de otras publicaciones / blogs podrían manejar todos los escenarios (por ejemplo, números negativos y algunos "números de la suerte" que encontró nuestro probador). Al final, nuestro probador no encontró ningún problema con este método a continuación. Pegar un fragmento de mi código:

fixPrecision: function (value) {
    var me = this,
        nan = isNaN(value),
        precision = me.decimalPrecision;

    if (nan || !value) {
        return nan ? '' : value;
    } else if (!me.allowDecimals || precision <= 0) {
        precision = 0;
    }

    //[1]
    //return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
    precision = precision || 0;
    var negMultiplier = value < 0 ? -1 : 1;

    //[2]
    var numWithExp = parseFloat(value + "e" + precision);
    var roundedNum = parseFloat(Math.round(Math.abs(numWithExp)) + 'e-' + precision) * negMultiplier;
    return parseFloat(roundedNum.toFixed(precision));
},

También tengo comentarios de código (lo siento, ya olvidé todos los detalles) ... Estoy publicando mi respuesta aquí para referencia futura:

9.995 * 100 = 999.4999999999999
Whereas 9.995e2 = 999.5
This discrepancy causes Math.round(9.995 * 100) = 999 instead of 1000.
Use e notation instead of multiplying /dividing by Math.Pow(10,precision).
remondo
fuente
0

Estoy arreglando el problema del modificador. Soporta solo 2 decimales.

$(function(){
  //input number only.
  convertNumberFloatZero(22); // output : 22.00
  convertNumberFloatZero(22.5); // output : 22.50
  convertNumberFloatZero(22.55); // output : 22.55
  convertNumberFloatZero(22.556); // output : 22.56
  convertNumberFloatZero(22.555); // output : 22.55
  convertNumberFloatZero(22.5541); // output : 22.54
  convertNumberFloatZero(22222.5541); // output : 22,222.54

  function convertNumberFloatZero(number){
	if(!$.isNumeric(number)){
		return 'NaN';
	}
	var numberFloat = number.toFixed(3);
	var splitNumber = numberFloat.split(".");
	var cNumberFloat = number.toFixed(2);
	var cNsplitNumber = cNumberFloat.split(".");
	var lastChar = splitNumber[1].substr(splitNumber[1].length - 1);
	if(lastChar > 0 && lastChar < 5){
		cNsplitNumber[1]--;
	}
	return Number(splitNumber[0]).toLocaleString('en').concat('.').concat(cNsplitNumber[1]);
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

bamossza
fuente
0
(Math.round((10.2)*100)/100).toFixed(2)

Eso debería producir: 10.20

(Math.round((.05)*100)/100).toFixed(2)

Eso debería producir: 0.05

(Math.round((4.04)*100)/100).toFixed(2)

Eso debería producir: 4.04

etc.

Anthony Ruffino
fuente
0

/*Due to all told stuff. You may do 2 things for different purposes:
When showing/printing stuff use this in your alert/innerHtml= contents:
YourRebelNumber.toFixed(2)*/

var aNumber=9242.16;
var YourRebelNumber=aNumber-9000;
alert(YourRebelNumber);
alert(YourRebelNumber.toFixed(2));

/*and when comparing use:
Number(YourRebelNumber.toFixed(2))*/

if(YourRebelNumber==242.16)alert("Not Rounded");
if(Number(YourRebelNumber.toFixed(2))==242.16)alert("Rounded");

/*Number will behave as you want in that moment. After that, it'll return to its defiance.
*/

Christian Læirbag
fuente
0

Esto es muy simple y funciona tan bien como cualquiera de los otros:

function parseNumber(val, decimalPlaces) {
    if (decimalPlaces == null) decimalPlaces = 0
    var ret = Number(val).toFixed(decimalPlaces)
    return Number(ret)
}

Como toFixed () solo se puede invocar en números, y desafortunadamente devuelve una cadena, esto hace todo el análisis por usted en ambas direcciones. ¡Puedes pasar una cadena o un número, y obtienes un número cada vez! Llamar a parseNumber (1.49) le dará 1, y parseNumber (1.49,2) le dará 1.50. ¡Como el mejor de ellos!

Aaron Dake
fuente
0

También puede usar el .toPrecision()método y algún código personalizado, y siempre redondear al enésimo dígito decimal independientemente de la longitud de la parte int.

function glbfrmt (number, decimals, seperator) {
    return typeof number !== 'number' ? number : number.toPrecision( number.toString().split(seperator)[0].length + decimals);
}

También podría convertirlo en un complemento para un mejor uso.

leo_lo
fuente
-1

Tan simple como esto.

var rounded_value=Math.round(value * 100) / 100;
Gihan Gamage
fuente
1
Incorrecto. Pruebe 1.015
Marco Marsala
-2

Encontré una manera muy simple que resolvió este problema para mí y puede usarse o adaptarse:

td[row].innerHTML = price.toPrecision(price.toFixed(decimals).length

fuente
-4

100% trabajando !!! Intentalo

<html>
     <head>
      <script>
      function replacePonto(){
        var input = document.getElementById('qtd');
        var ponto = input.value.split('.').length;
        var slash = input.value.split('-').length;
        if (ponto > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        if(slash > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        input.value=input.value.replace(/[^0-9.-]/,'');

        if (ponto ==2)
	input.value=input.value.substr(0,(input.value.indexOf('.')+3));

if(input.value == '.')
	input.value = "";
              }
      </script>
      </head>
      <body>
         <input type="text" id="qtd" maxlength="10" style="width:140px" onkeyup="return replacePonto()">
      </body>
    </html>

JONAS MAGALHAES DOS SANTOS
fuente
Bienvenido a SO. Lea este tutorial y siga las pautas para responder.
2017