Saltar al contenido
Curso de JavaScriptModerno · Interactivo

Unidad 4 · Lecciones 023-028

Numeros en JavaScript

Cuantos me gusta tiene una publicacion, cuantos seguidores tienes, cuanto hay que pagar por un pedido: los numeros estan en todas partes. En JavaScript todos los numeros se crean igual, sean enteros, decimales o negativos, lo cual simplifica mucho las cosas.

📚 6 lecciones originales ⏱ Lectura ~25 min ↩ Requiere: Unidades 2 y 3

🎯 Objetivo de aprendizaje

Al terminar sabras operar con numeros, controlar el orden en que se ejecutan las operaciones, usar las funciones del objeto Math, incrementar o decrementar valores y convertir texto en numero para poder compararlo.

4.1 Crear numeros

💡 La regla que lo simplifica todo

En otros lenguajes hay que declarar si un numero es entero (int) o decimal (float). En JavaScript no: enteros, decimales, fracciones y negativos se escriben exactamente igual.

Todos se crean igual
const numero1 = 30;         // entero
const numero2 = 20.20;      // decimal
const numero3 = .102030;    // tambien vale empezar por el punto
const numero4 = -20;        // negativo

console.log(numero1);
console.log(numero2);
console.log(numero3);
console.log(numero4);

Numero frente a texto que parece numero

Esta es la distincion mas importante de la unidad. Si pones comillas, ya no es un numero: es un string que parece un numero.

La diferencia esta en las comillas
const numero1 = 20;      // NUMERO
const numero2 = '20';    // STRING

console.log(numero1);
console.log(numero2);

console.log(typeof numero1);   // number
console.log(typeof numero2);   // string

+ Como verlo en tu consola

En la consola de Chrome los numeros aparecen en azul y los strings en negro. Es una forma rapida de detectar si un dato es lo que crees que es. El operador typeof, que se explica a fondo en la Unidad 5, te lo dice explicitamente.

La forma con constructor

new Number()
const numero6 = new Number(80);

console.log(numero6);           // un objeto que envuelve el 80
console.log(typeof numero6);    // object, NO number

Igual que con los strings, esta forma crea un objeto, no un numero primitivo. Casi no se usa.

4.2 Operaciones basicas

Las cinco operaciones
const numero1 = 30;
const numero2 = 20;
let resultado;

// Suma
resultado = numero1 + numero2;
console.log('Suma:', resultado);            // 50

// Resta
resultado = numero1 - numero2;
console.log('Resta:', resultado);           // 10

// Multiplicacion
resultado = numero1 * numero2;
console.log('Multiplicacion:', resultado);  // 600

// Division
resultado = numero1 / numero2;
console.log('Division:', resultado);        // 1.5

// Modulo: el RESIDUO de la division
resultado = numero1 % numero2;
console.log('Modulo:', resultado);          // 10

💡 Que es el modulo

El simbolo % no calcula un porcentaje: devuelve lo que sobra al dividir. 30 % 20 es 10 porque 20 cabe una vez en 30 y sobran 10.

Parece un detalle menor, pero es la herramienta estandar para saber si un numero es par: si n % 2 vale 0, es par. Lo usaras en la Unidad 11 y en el ejercicio FizzBuzz.

⚠ El signo + tiene dos personalidades

Con dos numeros, suma. Con texto, concatena (lo viste en la Unidad 3). JavaScript decide en funcion del tipo de los operandos.

Suma o concatena segun el tipo
console.log(30 + 20);       // 50   -> los dos son numeros: suma
console.log('30' + 20);     // '3020' -> uno es texto: concatena
console.log('30' - 20);     // 10   -> el operador - solo existe para numeros,
                            //         asi que JavaScript convierte el string

4.3 El objeto Math

Math es un objeto que existe siempre, en cualquier lugar del codigo (esta en la ventana global). Agrupa constantes y funciones matematicas. Se accede a ellas con la sintaxis de punto.

Redondeo
// PI, una constante
console.log(Math.PI);

// round: redondeo normal (.5 sube)
console.log(Math.round(2.8));   // 3
console.log(Math.round(2.2));   // 2
console.log(Math.round(2.5));   // 3

// ceil: SIEMPRE hacia arriba
console.log(Math.ceil(2.1));    // 3
console.log(Math.ceil(2.5));    // 3

// floor: SIEMPRE hacia abajo
console.log(Math.floor(2.9));   // 2
Math.round()
Redondea al entero mas cercano. Desde .5 sube.
Math.ceil()
Fuerza hacia arriba: 2.01 ya se convierte en 3.
Math.floor()
Fuerza hacia abajo: 2.99 se queda en 2.
Math.abs()
Valor absoluto: ignora el signo negativo.
Otras funciones utiles
// Raiz cuadrada
console.log(Math.sqrt(144));        // 12

// Valor absoluto: quita el signo negativo
console.log(Math.abs(-200));        // 200
console.log(Math.abs(-500));        // 500

// Potencia: 8 elevado a 3
console.log(Math.pow(8, 3));        // 512
console.log(Math.pow(2, 4));        // 16

// Minimo y maximo de una serie de valores
console.log(Math.min(3, 5, 1, 12, -3));   // -3
console.log(Math.max(3, 5, 1, 12, -3));   // 12

Math.random() y como hacerlo util

Math.random() devuelve un decimal entre 0 y 1. Por si solo no sirve de mucho; lo util es combinarlo para obtener un entero dentro de un rango.

De 0.xxxx a un numero utilizable
// Solo, devuelve algo como 0.8437291...
console.log(Math.random());

// Multiplicado por 30, un decimal entre 0 y 30
console.log(Math.random() * 30);

// Redondeado hacia abajo: un ENTERO entre 0 y 29
console.log(Math.floor(Math.random() * 30));

Por que funciona

  1. Math.random() da, por ejemplo, 0.7412.
  2. Multiplicado por 30 da 22.236.
  3. Math.floor() lo trunca a 22.

Ideal para sortear un ganador, elegir una pregunta al azar en un test o barajar contenido.

+ Ampliacion pedagogica

La formula general para un entero entre min y max, ambos incluidos, es: Math.floor(Math.random() * (max - min + 1)) + min. El curso original solo muestra el caso desde 0; esta variante es la que necesitaras en un proyecto real.

4.4 El orden de las operaciones

Igual que en la escuela: multiplicaciones y divisiones primero, sumas y restas despues. Y los parentesis mandan sobre todo lo demas.

Sin y con parentesis
let resultado;

// Sin parentesis: primero 30 * 2 = 60, luego 20 + 60
resultado = 20 + 30 * 2;
console.log(resultado);     // 80

// Con parentesis: primero 20 + 30 = 50, luego 50 * 2
resultado = (20 + 30) * 2;
console.log(resultado);     // 100

Caso real: aplicar un descuento

20% de descuento sobre el carrito
// Sumamos todo el carrito y calculamos el 20%
const descuento = (20 + 30 + 40 + 50 + 60) * 0.20;

console.log('Total del carrito:', 20 + 30 + 40 + 50 + 60);  // 200
console.log('Descuento del 20%:', descuento);               // 40

✗ Sin parentesis el resultado es otro

Si escribieras 20 + 30 + 40 + 50 + 60 * 0.20, JavaScript aplicaria el 20% solo al ultimo numero y el resultado seria 152. Los parentesis no son decoracion.

Caso real: anadir un impuesto

Total con IVA del 16%
// Multiplicar por 1.16 anade el 16% en un solo paso
const total = (20 + 30) * 1.16;

console.log(total);   // 57.99999999999999

+ Ampliacion pedagogica: por que sale 57.99999...

No es un error tuyo. Los ordenadores guardan los decimales en binario y algunos valores no tienen representacion exacta, igual que 1/3 no se puede escribir con decimales finitos. Para mostrar dinero usa .toFixed(2), que devuelve un string con dos decimales:

toFixed para mostrar dinero
const total = (20 + 30) * 1.16;

console.log(total);              // 57.99999999999999
console.log(total.toFixed(2));   // '58.00'

4.5 Incrementos y decrementos

Sumar de uno en uno es tan comun (puntuaciones, contadores, indices de bucle) que el lenguaje tiene un atajo: ++. Y tiene una sutileza que se pregunta mucho en entrevistas.

Postfijo frente a prefijo

La diferencia entre puntaje++ y ++puntaje
let puntaje = 5;

// POSTFIJO: primero devuelve el valor, DESPUES incrementa
console.log(puntaje++);   // imprime 5
console.log(puntaje);     // ahora si vale 6

let puntaje2 = 5;

// PREFIJO: primero incrementa, DESPUES devuelve
console.log(++puntaje2);  // imprime 6 directamente

🎓 Pregunta de entrevista

¿Que imprime console.log(puntaje++) si puntaje vale 5?
Imprime 5, no 6. El valor se devuelve antes del incremento. Mucha gente responde 6. Con ++puntaje si imprimiria 6.

Decrementos

Restar de uno en uno
let puntaje = 5;

console.log(puntaje--);   // 5, y despues baja a 4
console.log(puntaje);     // 4

let vidas = 5;
console.log(--vidas);     // 4 directamente

Incrementar de N en N

En un juego de futbol cada gol vale 1, pero en baloncesto vale 2 o 3. Para eso estan += y -=:

Sumar y restar cantidades
let puntaje = 5;

puntaje += 3;            // equivale a: puntaje = puntaje + 3
console.log(puntaje);    // 8

puntaje += 3;
console.log(puntaje);    // 11

puntaje -= 3;            // equivale a: puntaje = puntaje - 3
console.log(puntaje);    // 8

⚠ Tiene que ser let

Todo lo de esta seccion reasigna la variable, asi que no puede declararse con const. Es uno de los casos claros donde let es la opcion correcta.

4.6 Convertir strings a numeros

Las bases de datos y los formularios HTML devuelven casi todo como texto. Si intentas hacer cuentas con '20' tendras problemas. Estas funciones lo resuelven.

parseInt y parseFloat
const numero1 = '20';      // string con forma de entero
const numero2 = '20.2';    // string con forma de decimal
const numero3 = 'uno';     // string que NO es un numero
const numero4 = 20;        // ya es numero

// parseInt -> convierte a entero
console.log(Number.parseInt(numero1));     // 20   (en azul: ya es numero)
console.log(Number.parseInt(numero2));     // 20   <-- pierde los decimales

// parseFloat -> conserva los decimales
console.log(Number.parseFloat(numero2));   // 20.2

// Si el texto no representa un numero:
console.log(Number.parseInt(numero3));     // NaN = Not a Number
parseInt()
Convierte a numero entero. Descarta la parte decimal.
parseFloat()
Convierte a numero con decimales.
NaN
Not a Number. Lo que obtienes al intentar convertir algo que no representa un numero.
Number.isInteger()
Comprueba si un valor es un entero. Devuelve true o false.
Comprobar antes de convertir
console.log(Number.isInteger(20));      // true
console.log(Number.isInteger(20.2));    // false
console.log(Number.isInteger('uno'));   // false
console.log(Number.isInteger('20'));    // false  <-- es un STRING, no un entero

💡 Flujo recomendado

  1. Comprueba primero si el valor puede convertirse.
  2. Convierte con parseInt o parseFloat segun necesites decimales.
  3. Ya puedes operar y comparar con seguridad.

⚠ Number es palabra reservada

Number, igual que Math, es un objeto global del lenguaje. No llames Number a una variable tuya.

4.7 Ejercicios practicos

Ejercicio 1

Ticket de compra

Tienes tres articulos con precios 340, 120 y 89. Calcula el subtotal, un descuento del 15%, el total tras el descuento y el total final con un 16% de impuesto. Muestra cada paso con template strings y el total final con dos decimales.

Ver solucion
Solucion
const articulo1 = 340;
const articulo2 = 120;
const articulo3 = 89;

const subtotal = articulo1 + articulo2 + articulo3;
const descuento = subtotal * 0.15;
const conDescuento = subtotal - descuento;
const totalFinal = conDescuento * 1.16;

console.log(`Subtotal: ${subtotal}`);
console.log(`Descuento 15%: ${descuento}`);
console.log(`Tras descuento: ${conDescuento}`);
console.log(`Total con IVA: ${totalFinal.toFixed(2)}`);

Fijate en que cada paso se guarda en su propia constante. Es mas legible que meterlo todo en una formula gigante, y mucho mas facil de depurar si algo no cuadra.

Ejercicio 2

Sorteo

Genera un numero entero al azar entre 1 y 100 (ambos incluidos) y muestralo con un mensaje.

Ver solucion
Solucion
const min = 1;
const max = 100;

const ganador = Math.floor(Math.random() * (max - min + 1)) + min;

console.log(`El numero ganador es el ${ganador}`);

Pulsa Ejecutar varias veces: cada vez sale un numero distinto.

Reto

Datos sucios de la base de datos

Una consulta te devuelve tres precios como texto: '340', '119.99' y 'ochenta'. Convierte los que se puedan, detecta el que no, y muestra la suma de los validos.

Ver solucion
Solucion
const precio1 = '340';
const precio2 = '119.99';
const precio3 = 'ochenta';

const n1 = Number.parseFloat(precio1);
const n2 = Number.parseFloat(precio2);
const n3 = Number.parseFloat(precio3);

console.log('precio1 convertido:', n1);
console.log('precio2 convertido:', n2);
console.log('precio3 convertido:', n3);   // NaN

console.log('Suma de los validos:', (n1 + n2).toFixed(2));

// Que pasa si sumas un NaN:
console.log('Sumando el invalido:', n1 + n2 + n3);   // NaN contagia todo

💡 Leccion importante

NaN contamina cualquier operacion: basta un valor invalido para que toda la suma se convierta en NaN. Por eso conviene validar los datos antes de operar con ellos.

4.8 Resumen de lo aprendido

  • Todos los numeros se crean igual: no existen tipos separados para enteros y decimales.
  • Con comillas ya no es un numero, es un string. typeof te lo confirma.
  • Cinco operadores: + - * / y % (el modulo: el residuo de la division).
  • El + concatena si alguno de los operandos es texto.
  • Math agrupa las funciones matematicas: round, ceil, floor, abs, sqrt, pow, min, max, random.
  • Orden de operaciones: multiplicaciones y divisiones antes que sumas y restas; los parentesis mandan.
  • Incrementos: n++ devuelve y luego suma; ++n suma y luego devuelve. += y -= para cantidades mayores.
  • Conversion: parseInt a entero, parseFloat con decimales, NaN cuando no se puede, Number.isInteger() para comprobar.

4.9 Verificacion de cierre

Con let puntaje = 5;, ¿que imprime console.log(puntaje++)?

  • 5
  • 6
  • undefined
  • Un error

¿Cuanto vale 17 % 5?

  • 3.4
  • 3
  • 2
  • 340

¿Cual de estas devuelve 2 a partir de 2.9?

  • Math.round(2.9)
  • Math.ceil(2.9)
  • Math.abs(2.9)
  • Math.floor(2.9)

🏁 Unidad completada