lunes, 30 de julio de 2012

Redondeos en JavaScript

Buenas a todos!!
Todos los que hemos trabajado con operaciones numéricas en el navegador, nos hemos encontrado con el problema de los redondeos. No es un problema que únicamente se encuentre en aplicaciones de gestión para realizar operaciones entre campos de un formulario, también es muy común tener que realizar redondeos en los juegos, sobretodo para calcular nuevas coordenadas de posición, o vectores, etc.

Existen diferentes problemas:
- Tengo un número decimal y quiero transformarlo en un número entero!
- Tengo un número decimal y quiero quitarle decimales, pero que estos decimales queden redondeados!
- Tengo un número decimal y quiero quitarle decimales, pero que el decimal final no quede redondeado!

Redondeo: convertir número decimal a número entero

Tenemos dos opciones, emplear la función Math.round o el desplazamiento de bits (bit shifting),
actualmente el bit shifting es la opción que presenta un mejor rendimiento en la mayoría de navegadores, así que es la que recomiendo utilizar.

Bit shifting:
var a = 14.678;
var b = (0.5 + (a)) << 0;

Math.round():
var a = 14.678;
var b = Math.round(a);

Ambos métodos obtienen el mismo resultado, la variable b contiene el valor 15.

Redondeo: redondear un número decimal a un número de decimales concreto

Supongamos que quiero únicamente quedarme con 2 decimales:
Math.round():
var a = 14.678;
var b = Math.round(a*100)/100;

number.toFixed(x):
var a = 14.678;
var b = parseFloat(a.toFixed(2));

Con esto, la variable b contiene el valor 15.68.

Es importante que indique, que la función toFixed(x) es una función para dar formato a un número decimal y que el valor que retorna no es un valor númerico, es un String, por esa razón si queremos realizar operaciones con la variable b, es necesario hacer el casting a float, con parseFloat().

Mucha gente se encuentra con el problema de que está trabajando con toFixed, y que al realizar operaciones con un número convertido usando toFixed, el número resultante es el temido NaN (Not a Number), miran en el log o realizan alerts, y ven que el número es correcto!, tras varios siglos volviéndose locos se dan cuenta de que era un STRING!!

Eliminar decimales de un número sin redondearlo

Ahora no deseamos que se realice ese redondeo final en los decimales:
Bit shifting:
var a = 14.678;
var b = ((a*100) << 0) / 100;

La variable b contiene el valor 15.67.

Bien! Espero haber resuelto dudas sobre este tema!
Un saludo a todos!!