Pregunta

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í.

¿Fue útil?

Solución

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

(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 en realidad no redondea, el 90% del tiempo, devolverá el valor redondeado, pero para muchos casos en realidad no funciona. Prueba esto en tu consola:

2.005.toFixed(2)

Obtendrás la respuesta incorrecta

No hay una forma natural de obtener un redondeo decimal en JavaScript, necesitará su propio polyfill o usar una biblioteca. Puedes mirar el polyfill de Mozilla para esto https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/math/round

Otros consejos

Este es un tema antiguo, pero aún así, los resultados de Google de primer nivel y las soluciones ofrecidas comparten el mismo problema de decimales de punto 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

Esta genericidad también proporciona algunas cosas geniales:

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

Ahora, para responder a 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 y 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!):

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));
}
function naive(value, exp) {
  if (!exp) {
    return Math.round(value);
  }
  var pow = Math.pow(10, exp);
  return Math.round(value * pow) / pow;
}
function test(val, places) {
  subtest(val, places);
  val = typeof val === "string" ? "-" + val : -val;
  subtest(val, places);
}
function subtest(val, places) {
  var placesOrZero = places || 0;
  var naiveResult = naive(val, places);
  var roundResult = round(val, places);
  if (placesOrZero >= 0) {
    naiveResult = naiveResult.toFixed(placesOrZero);
    roundResult = roundResult.toFixed(placesOrZero);
  } else {
    naiveResult = naiveResult.toString();
    roundResult = roundResult.toString();
  }
  $("<tr>")
    .append($("<td>").text(JSON.stringify(val)))
    .append($("<td>").text(placesOrZero))
    .append($("<td>").text(naiveResult))
    .append($("<td>").text(roundResult))
    .appendTo("#results");
}
test(0.565, 2);
test(0.575, 2);
test(0.585, 2);
test(1.275, 2);
test(1.27499, 2);
test(1234.5678, -2);
test(1.2345678e+2, 2);
test("123.45");
test(10.8034, 2);
test(10.8, 2);
test(1.005, 2);
test(1.0005, 2);
table {
  border-collapse: collapse;
}
table, td, th {
  border: 1px solid #ddd;
}
td, th {
  padding: 4px;
}
th {
  font-weight: normal;
  font-family: sans-serif;
}
td {
  font-family: monospace;
}
<table>
  <thead>
    <tr>
      <th>Input</th>
      <th>Places</th>
      <th>Naive</th>
      <th>Thorough</th>
    </tr>
  </thead>
  <tbody id="results">
  </tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Por lo general, agrego esto a mi biblioteca personal, y después de algunas sugerencias y usando la solución @Timineutron también, y lo hago adaptable para la longitud decimal, esta es 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.

No sé por qué no puedo agregar un comentario a una respuesta anterior (tal vez soy irremediablemente 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 regresar 1.28
  • Problema con precise_round(6,2) No regresar 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 dado que Math.round es con los que es con pérdida, puede verificarlo en jsfiddle.net, esta es la única forma en que sabía cómo "arreglar " eso). Agrega 0.001 al número ya acolchado, por lo que está agregando un 1 Tres 0s a la derecha del valor decimal. Por lo tanto, debería 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).

Así que eso es todo. Úsalo bien ;)

Editar: Se agregó funcionalidad a la "corrección" de números negativos.

Una forma de estar 100% seguro de que obtienes 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)

tofixed (n) proporciona una longitud de n 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 se use

result = num.toFixed(2);

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

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

@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
    });
});

Demostración en línea:

http://jsfiddle.net/c4Wqn/

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 alert(roundFloat(1.79209243929,4));

Jsfiddle

El problema con los valores de los puntos flotantes 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 vas a ser mordido con algunos valores.

Cuando una computadora almacena 1.275 como valor de punto flotante, en realidad no recordará si fue 1.275 o 1.274999999999999993, o incluso 1.27500000000000002. Estos valores deberían dar diferentes resultados después del redondeo a dos decimales, pero no lo harán, ya que para la computadora miran exactamente lo mismo Después de almacenar como valores de punto flotante, y no hay forma de restaurar los datos perdidos. Cualquier cálculo adicional solo acumulará dicha imprecisión.

Entonces, si la precisión importa, debe evitar los valores de puntos flotantes desde el principio. Las opciones más simples son

  • utilizar una biblioteca dedicada
  • Use cadenas para almacenar y pasar los valores (acompañado de operaciones de cadena)
  • Use enteros (por ejemplo, podría pasar alrededor de 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 usa enteros para almacenar el número de centésimas, 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 cuerdas, 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 redondea al más cercano, Atacas de cero, tiempo IEEE 754 recomienda redondear al más cercano, lazos a incluso como el comportamiento predeterminado para las operaciones de puntos flotantes. Tales modificaciones se dejan como un ejercicio para el lector :)

Redondea tu valor decimal, luego usa toFixed(x) para sus dígitos esperados.

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

Llamar

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

/**
 * 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

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

Esto es lo que pasa:

1) Primero, usted solicita .toFixed(2) sobre el número que desea completar los lugares decimales de. Tenga en cuenta que esto convertirá el valor en una cadena desde el número. Entonces, si está usando TypeScript, lanzará un error como este:

"Tipo 'String' no se puede asignar para escribir 'Número'"

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

Para una aclaración, mire el ejemplo a continuación:

EJEMPLO:Tengo una cantidad que tiene hasta 5 dígitos en los lugares decimales y me gustaría acortarlo a 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);

Poner el seguimiento En algún alcance global:

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

y entonces intenta:

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

Actualizar

Tenga en cuenta que toFixed() solo puede funcionar para el número de decimales entre 0-20 es decir a.getDecimals(25) Puede generar un error de JavaScript, por lo que para acomodar que puede agregar un cheque adicional, es decir,

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

Esto devolverá un número aleatorio de 1 a 100 redondeados a 2 decimales.

Number(Math.round(1.005+'e2')+'e-2'); // 1.01

Esto funcionó para mí: Redondeo de decimales en JavaScript

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/

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>

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.

Con estos ejemplos, aún recibirá un error al intentar 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);
}

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 suerte" que nuestro probador encontró). 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).

Estoy solucionando el problema el modificador.Apoyo 2 decimal solamente.

$(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>

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

Que debería ceder: 10.20

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

Que debería ceder: 0.05

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

Que debería ceder: 4.04

etc.

/*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.
*/

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)
}

Dado que Tofixed () solo se puede llamar a los números, y desafortunadamente devuelve una cadena, esto hace todo el análisis por usted en ambas direcciones. Puede pasar una cadena o un número, ¡y obtendrá un número cada vez! Llamar a Parsenumber (1.49) le dará 1, y Parsenumber (1.49,2) le dará 1.50. ¡Como lo mejor de ellos!

También podrías usar el .toPrecision() método y algún código personalizado, y siempre redondea el 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.

Simple por este.

var rounded_value=Math.round(value * 100) / 100;

Encontré una manera muy simple que resolvió este problema para mí y se puede usar o adaptar:

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

100% funcionando !!! 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>

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top