Number
El tipo number
en JavaScript representa tanto números enteros como decimales. A diferencia de otros lenguajes que tienen tipos separados para enteros y flotantes, JavaScript unifica todo en un solo tipo number
.
Características del tipo Number
JavaScript usa el estándar IEEE 754 para representar números, lo que significa:
- 64 bits de precisión (double precision)
- Rango aproximado: ±1.7976931348623157 × 10^308
- 15-17 dígitos de precisión decimal
- Incluye valores especiales:
Infinity
,-Infinity
yNaN
// Todos estos son tipo 'number'
let entero = 42
let decimal = 3.14159
let negativo = -17
let exponencial = 1.5e10 // 15000000000
let hexadecimal = 0xff // 255
let binario = 0b1010 // 10
let octal = 0o777 // 511
console.log(typeof entero) // "number"
console.log(typeof decimal) // "number"
Creación de números
Para crear un número en JavaScript... sólo tienes que escribirlo. Lo interesante es que además podemos directamente usar diferentes notaciones, como hemos visto antes, para crear números binarios, hexadecimales, octales y demás.
1. Literals numéricos (la forma más común)
// Enteros
let edad = 25
let temperatura = -5
// Decimales
let precio = 19.99
let pi = 3.14159
// Notación científica
let distancia = 1.5e8 // 150,000,000
let pequeño = 2.5e-4 // 0.00025
// Diferentes bases
let hexColor = 0xff0000 // 16777216 (rojo en hex)
let binario = 0b11111111 // 255
let octal = 0o377 // 255 (base 8)
2. Constructor Number()
Si necesitas crear un número a partir de otro tipo de dato, como string, o desde una variable, puedes usar el constructor Number()
. ¡Fíjate que no usamos new
al llamarlo! Esto es un detalle importante.
// Crear primitivo
let numero = Number('42') // 42
let decimal = Number('3.14') // 3.14
let string = '42'
let desdeString = Number(string) // 42
console.log(typeof desdeString) // "number"
// ❌ NO hagas esto, ya que con new creas un objeto
let numeroObjeto = new Number(42)
console.log(typeof numeroObjeto) // "object"
3. Conversión desde otros tipos
Por la naturaleza de JavaScript, vas a poder pasarle casi cualquier cosa a Number()
e intentará hacer su mejor esfuerzo para convertirlo a número. Ten en cuenta que en algunos casos, el resultado te puede sorprender:
// Desde booleanos
let desde_true = Number(true) // 1
let desde_false = Number(false) // 0
// Casos especiales
let desde_null = Number(null) // 0
let desde_undefined = Number(undefined) // NaN
let desde_string_vacia = Number('') // 0
let desde_string_invalida = Number('abc') // NaN
Valores especiales
Hay unas constantes en el objeto Number
que representan valores especiales. Además, también hay algunos valores que no se pueden representar con números, como el infinito, el negativo infinito y el NaN.
Además, Number
tiene algunos métodos que te ayudarán a verificarlos.
Infinity y -Infinity
// Infinity
console.log(1 / 0) // Infinity
console.log(Number.POSITIVE_INFINITY) // Infinity
console.log(Math.pow(10, 1000)) // Infinity
// -Infinity
console.log(-1 / 0) // -Infinity
console.log(Number.NEGATIVE_INFINITY) // -Infinity
// Verificar si es infinito
console.log(Number.isFinite(42)) // true
console.log(Number.isFinite(Infinity)) // false
console.log(isFinite(42)) // true (función global)
NaN (Not a Number)
NaN
es un valor especial que representa un resultado de una operación matemática que no es un número, de ahí su nombre: Not A Number
(no es un número).
Ten en cuenta que NaN
es un valor de tipo number
. Sí, sé que suena contradictorio. Pero no es un problema de JavaScript, como mucha gente piensa. En realidad es parte de la especificación del estándar IEEE 754 que así lo determina.
// Operaciones que resultan en NaN
console.log(0 / 0) // NaN
console.log(Math.sqrt(-1)) // NaN
console.log(Number('texto')) // NaN
console.log(undefined + 1) // NaN
Además, NaN
es el único valor en JavaScript que no es igual a sí mismo. Esto tampoco es un error del lenguaje, también es parte de la especificación del estándar IEEE 754.
// NaN es especial: no es igual a sí mismo
console.log(NaN === NaN) // false
console.log(NaN == NaN) // false
Además, Number
tiene algunos métodos que te ayudarán a verificarlos. Existen dos métodos para hacerlo isNaN()
y Number.isNaN()
. ¿Cuál es la diferencia entre ambos y por qué hay dos?
isNaN()
: Convierte el valor a número primero y luego verifica si es NaN.Number.isNaN()
: No convierte el valor a número, solo verifica si ya es NaN.
console.log(isNaN('texto')) // true (convierte a número primero)
console.log(Number.isNaN('texto')) // false
isNaN()
es una función global y es más antigua.Number.isNaN()
es más nueva y sería la forma recomendada de verificar si un valor es NaN a día de hoy.
Propiedades estáticas importantes
Como hemos dicho, Number
tiene algunas propiedades estáticas que te pueden ser útiles para tener acceso a algunos valores especiales:
// Valores límite
console.log(Number.MAX_VALUE) // 1.7976931348623157e+308
console.log(Number.MIN_VALUE) // 5e-324 (más pequeño positivo)
console.log(Number.MAX_SAFE_INTEGER) // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER) // -9007199254740991
// Constantes especiales
console.log(Number.POSITIVE_INFINITY) // Infinity
console.log(Number.NEGATIVE_INFINITY) // -Infinity
console.log(Number.NaN) // NaN
// Epsilon (diferencia mínima entre números)
console.log(Number.EPSILON) // 2.220446049250313e-16
Métodos de Number
Una vez tenemos un número
Métodos de conversión
let numero = 123.456789
// toString - convierte a string
console.log(numero.toString()) // "123.456789"
console.log(numero.toString(2)) // "1111011.0111010..." (binario)
console.log(numero.toString(16)) // "7b.74bc6a7ef9db2" (hexadecimal)
// toFixed - fija decimales
console.log(numero.toFixed(2)) // "123.46"
console.log(numero.toFixed(0)) // "123"
// toPrecision - fija dígitos significativos
console.log(numero.toPrecision(4)) // "123.5"
console.log(numero.toPrecision(2)) // "1.2e+2"
// toExponential - notación científica
console.log(numero.toExponential()) // "1.23456789e+2"
console.log(numero.toExponential(2)) // "1.23e+2"
Métodos estáticos de verificación
// isInteger - verifica si es entero
console.log(Number.isInteger(42)) // true
console.log(Number.isInteger(42.0)) // true
console.log(Number.isInteger(42.1)) // false
// isSafeInteger - verifica si está en rango seguro
console.log(Number.isSafeInteger(123)) // true
console.log(Number.isSafeInteger(Math.pow(2, 53))) // false
// isFinite - verifica si es finito
console.log(Number.isFinite(42)) // true
console.log(Number.isFinite(Infinity)) // false
// isNaN - verifica si es NaN
console.log(Number.isNaN(NaN)) // true
console.log(Number.isNaN('texto')) // false
Métodos de parsing
// parseInt - convierte a entero
console.log(Number.parseInt('42')) // 42
console.log(Number.parseInt('42.7')) // 42
console.log(Number.parseInt('42px')) // 42
console.log(Number.parseInt('px42')) // NaN
// Con base específica
console.log(Number.parseInt('FF', 16)) // 255
console.log(Number.parseInt('1010', 2)) // 10
// parseFloat - convierte a decimal
console.log(Number.parseFloat('42.7')) // 42.7
console.log(Number.parseFloat('42.7px')) // 42.7
console.log(Number.parseFloat('px42.7')) // NaN
Operaciones matemáticas básicas
let a = 10
let b = 3
// Operadores básicos
console.log(a + b) // 13 (suma)
console.log(a - b) // 7 (resta)
console.log(a * b) // 30 (multiplicación)
console.log(a / b) // 3.3333333333333335 (división)
console.log(a % b) // 1 (módulo/resto)
console.log(a ** b) // 1000 (exponenciación)
// Operadores de incremento/decremento
let contador = 5
console.log(++contador) // 6 (pre-incremento)
console.log(contador++) // 6 (post-incremento, luego contador = 7)
console.log(--contador) // 6 (pre-decremento)
console.log(contador--) // 6 (post-decremento, luego contador = 5)
Precisión y problemas comunes
Sobre los problemas de precisión decimal
Como hemos visto, los números en JavaScript no son perfectos. Hay algunos problemas de precisión que debemos tener en cuenta.
Problema clásico de punto flotante
Este problema es muy conocido. Mucha gente, de forma erronea, cree que es algo específico de JavaScript. En realidad es algo que afecta a muchos lenguajes de programación.
// Problema clásico de punto flotante
console.log(0.1 + 0.2) // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3) // false
Esto ocurre porque los números en JavaScript se representan en formato binario de punto flotante, lo que puede causar errores de precisión a la hora de hacer operaciones.
// Soluciones
function sumarDecimales(a, b, decimales = 2) {
return Number((a + b).toFixed(decimales))
}
console.log(sumarDecimales(0.1, 0.2)) // 0.3
// Usando Number.EPSILON para comparaciones
function sonIguales(a, b) {
return Math.abs(a - b) < Number.EPSILON
}
console.log(sonIguales(0.1 + 0.2, 0.3)) // true
Conversiones automáticas (coerción)
Uno de los problemas más comunes que se pueden dar es cuando intentamos hacer operaciones con números y uno de ellos es un string. JavaScript intentará convertir el string a número y luego hacer la operación. A este paso se le conoce como coerción.
La coerción es un proceso que se realiza automáticamente por el lenguaje cuando intentamos hacer operaciones con valores de tipos diferentes. En este caso, si detecta que uno de los valores es un número y el otro es un string, intentará convertir el string a número y luego hacer la operación.
Siempre que puedas, deberías evitar esto y siempre trabajar con conversiones explícitas. Así te evitas sorpresas.
// Conversión implícita en operaciones
console.log('5' + 3) // "53" (concatenación)
console.log('5' - 3) // 2 (resta numérica)
console.log('5' * 3) // 15 (multiplicación)
console.log('5' / 3) // 1.6666... (división)
// Conversión con operador unario +
console.log(+'42') // 42
console.log(+true) // 1
console.log(+false) // 0
console.log(+'') // 0
El operador unario
+
es una forma de convertir un string a número, si no lo es ya.
Esta comparación
¿Cuál es el resultado de 0.1 + 0.2 === 0.3
en JavaScript?
¿Qué valor devuelve Number.isNaN("texto")
?
¿Cuál es la diferencia entre parseInt("42px")
y Number("42px")
?
¿Qué es Number.MAX_SAFE_INTEGER
?
¿Qué hace (123.456).toFixed(2)
?
¿Cuál es el resultado de NaN === NaN
?
🔒 Inicio sesión requerido
Para guardar tu progreso, necesitas iniciar sesión con uno de estos servicios:
Límites de enteros seguros
En JavaScript hay un límite de enteros seguros. Este límite es el número 2^53 - 1. Si intentas hacer operaciones con números más grandes que este límite, podrías perder precisión. Para saber cuál es el número más grande que se puede representar con precisión, puedes usar la propiedad Number.MAX_SAFE_INTEGER
.
// Enteros seguros
console.log(Number.MAX_SAFE_INTEGER) // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER + 1) // 9007199254740992
console.log(Number.MAX_SAFE_INTEGER + 2) // 9007199254740992 (¡es igual!)
Como ves en el código anterior, una vez que llegamos al límite de enteros seguros, cualquier operación que hagamos con ellos nos dará resultados inesperados así que ten cuidado.
Para hacer operaciones con números más grandes que el límite de enteros seguros, puedes usar el tipo
BigInt
. Lo veremos más adelante.
Palabras finales sobre number
- Un sólo tipo:
number
para enteros y decimales - IEEE 754: Estándar de punto flotante de 64 bits
- Valores especiales:
Infinity
,-Infinity
, yNaN
- Métodos útiles: Para conversión, formateo y validación
- Conversiones: Automáticas en muchas operaciones
- Limitaciones: Problemas de precisión y límites de enteros seguros
Es importante entender las limitaciones de precisión y usar las herramientas adecuadas para trabajar con números de manera segura y precisa.