BigInt
Una adición reciente
Esta es una incorporación relativamente nueva al lenguaje JavaScript. Puedes comprobar el soporte actual en los navegadores en https://caniuse.com/#feat=bigint.
BigInt es un tipo numérico especial que permite manejar enteros de tamaño arbitrario.
Un BigInt se puede crear añadiendo una n
al final del literal entero o invocando la función BigInt
, la cual convierte cadenas, números y otros tipos a BigInt.
const bigint = 1234567890123456789012345678901234567890n;
const sameBigint = BigInt("1234567890123456789012345678901234567890");
const bigintFromNumber = BigInt(10); // equivalente a 10n
Operadores matemáticos
BigInt puede usarse de manera similar a los números regulares, por ejemplo:
alert(1n + 2n); // 3n
alert(5n / 2n); // 2n
Es importante tener en cuenta que la división como 5/2
devuelve el resultado redondeado hacia abajo, sin decimales. Todas las operaciones con BigInts devuelven BigInts.
No podemos mezclar BigInts con números normales directamente:
alert(1n + 2); // Error: No se puede mezclar BigInt con otros tipos.
Podemos convertir explícitamente cuando sea necesario usando BigInt()
o Number()
, como se muestra a continuación:
let bigint = 1n;
let number = 2;
// De número a BigInt
alert(bigint + BigInt(number)); // 3n
// De BigInt a número
alert(Number(bigint) + number); // 3
Las conversiones son silenciosas y no generan errores, pero si el BigInt es demasiado grande para caber en un tipo numérico, los bits extra serán descartados, así que debemos ser cautelosos al hacer esta conversión.
El operador unario más no es compatible con BigInts
El operador unario +value
es una forma común de convertir value
a número.
Para evitar confusiones, esto no es soportado con BigInts:
let bigint = 1n;
alert(+bigint); // Error
Debemos usar Number()
para convertir un BigInt a número.
Comparaciones
Las comparaciones como <
, >
funcionan correctamente entre BigInts y números:
alert(2n > 1n); // true
alert(2n > 1); // true
Es importante notar que, dado que los números y los BigInts pertenecen a tipos diferentes, pueden ser iguales ==
, pero no estrictamente iguales ===
:
alert(1 == 1n); // true
alert(1 === 1n); // false
Operaciones booleanas
En un if
u otra operación booleana, los BigInts se comportan como números.
Por ejemplo, en un if
, el BigInt 0n
es falso, mientras que otros valores son verdaderos:
if (0n) {
// nunca se ejecuta
}
Los operadores booleanos como ||
, &&
, y otros, también funcionan con BigInts de manera similar a los números:
alert(1n || 2); // 1n (1n es considerado verdadero)
alert(0n || 2); // 2 (0n es considerado falso)
Polyfills
Crear un polyfill para BigInts es complicado. La razón es que muchos operadores de JavaScript como +
, -
, y otros, se comportan de manera diferente comparados con los números regulares.
Por ejemplo, la división de BigInts siempre devuelve un BigInt (redondeado si es necesario).
Para emular este comportamiento, un polyfill necesitaría analizar el código y reemplazar todos los operadores con sus funciones. Pero esto es complejo y puede afectar el rendimiento.
Por lo tanto, no existe un buen polyfill conocido.
Sin embargo, hay otra solución propuesta por los desarrolladores de la librería JSBI.
Esta librería implementa BigInt usando sus propios métodos. Podemos usarlos en lugar de BigInts nativos:
Operación | BigInt nativo | JSBI |
---|---|---|
Creación desde Number | a = BigInt(789) | a = JSBI.BigInt(789) |
Suma | c = a + b | c = JSBI.add(a, b) |
Resta | c = a – b | c = JSBI.subtract(a, b) |
… | … | … |
Y luego, usar un polyfill (plugin Babel) para convertir las llamadas de JSBI en BigInts nativos para aquellos navegadores que los soporten.
En otras palabras, este enfoque sugiere escribir código usando JSBI en lugar de BigInts nativos. JSBI trabaja internamente con números y BigInts, emulándolos siguiendo de cerca la especificación, haciendo que el código esté «preparado para BigInt».
Podemos usar este código JSBI «tal cual» en motores que no soportan BigInts, y para aquellos que sí los soportan, el polyfill convertirá las llamadas en BigInts nativos.