BigInt
es un tipo numérico especial que provee soporte a enteros de tamaño arbitrario.
Un bigint se crea agregando n
al final del literal entero o llamando a la función BigInt
que crea bigints desde cadenas, números, etc.
const bigint = 1234567890123456789012345678901234567890n;
const sameBigint = BigInt("1234567890123456789012345678901234567890");
const bigintFromNumber = BigInt(10); // lo mismo que 10n
Operadores matemáticos
BigInt
puede ser usado mayormente como un número regular, por ejemplo:
alert(1n + 2n); // 3
alert(5n / 2n); // 2
Por favor, ten en cuenta: la división 5/2
devuelve el resultado redondeado a cero, sin la parte decimal. Todas las operaciones sobre bigints devuelven bigints.
No podemos mezclar bigints con números regulares:
alert(1n + 2); // Error: No se puede mezclar BigInt y otros tipos.
Podemos convertirlos explícitamente cuando es necesario: usando BigInt()
o Number()
como aquí:
let bigint = 1n;
let number = 2;
// De number a bigint
alert(bigint + BigInt(number)); // 3
// De bigint a number
alert(Number(bigint) + number); // 3
Las operaciones de conversión siempre son silenciosas, nunca dan error, pero si el bigint es tan gigante que no podrá ajustarse al tipo numérico, los bits extra serán recortados, entonces deberíamos ser cuidadosos al hacer tal conversión.
El operador unario más +value
es una manera bien conocida de convertir value
a number.
Para evitar las confusiones, con bigints eso no es soportado:
let bigint = 1n;
alert( +bigint ); // error
Entonces debemos usar Number()
para convertir un bigint a number.
Comparaciones
Comparaciones tales como <
, >
funcionan bien entre bigints y numbers:
alert( 2n > 1n ); // true
alert( 2n > 1 ); // true
Por favor, nota que como number y bigint pertenecen a diferentes tipos, ellos pueden ser iguales ==
, pero no estrictamente iguales ===
:
alert( 1 == 1n ); // true
alert( 1 === 1n ); // false
Operaciones booleanas
Cuando están dentro de un if
u otra operación booleana, los bigints se comportan como numbers.
Por ejemplo, en if
, el bigint 0n
es falso, los otros valores son verdaderos:
if (0n) {
// nunca se ejecuta
}
Los operadores booleanos, tales como ||
, &&
y otros, también trabajan con bigints en forma similar a los number:
alert( 1n || 2 ); // 1 (1n es considerado verdadero)
alert( 0n || 2 ); // 2 (0n es considerado falso)
Polyfills
Hacer Polyfill con bigints es trabajoso. La razón es que muchos operadores JavaScript como +
, -
y otros se comportan de diferente manera comparados con los números regulares.
Por ejemplo, la división de bigints siempre devuelve un bigint (redondeado cuando es necesario).
Para emular tal comportamiento, un polyfill necesitaría analizar el código y reemplazar todos los operadores con sus funciones. Pero hacerlo es engorroso y tendría mucho costo en performance.
Por lo que no se conoce un buen polyfill.
Aunque hay otra manera, la 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 entonces usar polyfill (plugin Babel) para convertir las llamadas de JSBI en bigints nativos para aquellos navegadores que los soporten.
En otras palabras, este enfoque sugiere que escribamos código en JSBI en lugar de bigints nativos. Pero JSBI trabaja internamente tanto con numbers como con bigints, los emula siguiendo de cerca la especificación, entonces el código será “bigint-ready” (preparado para bigint).
Podemos usar tal código JSBI “tal como está” en motores que no soportan bigints, y para aquellos que sí lo soportan – el polyfill convertirá las llamadas en bigints nativos.