Вас, как фронтенд-разработчика, когда-нибудь беспокоили большие целые числа? JavaScript никогда не поддерживал большие целые числа. Если вы хотите работать с большими целыми числами, вы должны использовать сторонние библиотеки. Помимо проблем, могут возникнуть проблемы с чрезмерной упаковкой и эффективностью времени выполнения. В отличие от Java, уже давно существует метод, который может представлять произвольную точность.BigInteger
. А для JavaScript предложение в ECMAScriptBigInt
это новый числовой примитивный тип, который может представлять произвольную точность.
Эта статья в основном посвященаBigInt
Расскажите о его статусе, функциях, прогрессе и текущем использовании.
Номерные типы ограничений
в JavaScriptNumber
является типом с плавающей запятой двойной точности, что означает ограниченную точность.Number.MAX_SAFE_INTEGER
Он находится в пределах максимальной безопасности для2**53-1
. Минимальное безопасное значение равноNumber.MIN_SAFE_INTEGER
значение-((2**53)-1)
. Расчеты за пределами безопасных значений теряют точность. Как следует, вы можете видетьmax + 1
а такжеmax + 2
то же самое, что явно неправильно.
const max = Number.MAX_SAFE_INTEGER; // 9007199254740991
max + 1 // 9007199254740992
max + 2 // 9007199254740992
Что касается того, почему максимальное безопасное значение2**53-1
С IEEE float плавающее хранилище 754 может быть указано по ссылкеХватай хвостик данных — ловушка JS и решение с плавающей запятой.
В практических применениях, например, в большом целочисленном идентификаторе, точность временной техники будет вызывать проблемы небезопасными.Twitter IDs (snowflake)performance
объект сBigInt
// 1 毫秒(ms) = 1,000 微秒(μs) = 1,000,000 纳秒(ns) = 1,000,000,000 皮秒(ps)
const scale = 1000000000
const scaleBig = 1000000000n
const big = BigInt((performance.now() * scale).toFixed(0)) + BigInt(performance.timing.navigationStart) * scaleBig
const normal = (performance.now() + performance.timing.navigationStart) * scale
console.log(big) // 1550488515092440117252n 精确到皮秒
console.log(normal) // 1.550488515092455e+21 精确到微秒
在没有 BigInt 的时候,如果想要使用大整型,则不得不借助类似 BigInt 功能的第三方库。这有可能会影响 JavaScript 程序的效率,比如加载时间、解析时间、编译时间,以及运行时的效率。 На картинке нижеBigInt
Сравнение производительности с другими подобными сторонними библиотеками.
Особенности BigInt
BigInt
— это новый примитивный тип, позволяющий выполнять вычисления с произвольной точностью. СоздайтеBigInt
Значение типа также очень простое, просто добавьте число после числаn
Вот и все. Например,789
стали789n
. Вы также можете использовать глобальные методыBigInt(value)
Преобразование в цифровое эталонное значение или числовая строка. Например:
BigInt(1234567890) === 1234567890n // true
Другим примером является преобразование метки времени, описанное выше.
новый примитивный тип
теперь, когдаBigInt
это новый примитивный тип, то его можно использоватьtypeof
определить собственный тип
typeof 111 // "number"
typeof 111n // "bigint"
в то же времяBigInt
а такжеNumber
Значения типов также не являются строго равными.
111 === 111n // false
111 == 111n // true
В логике между цифровыми логическими значениямиBigInt
а такжеNumber
Стабильная производительность.
if (0n) {
console.log('if');
} else {
console.log('else');
}
// → logs 'else', because `0n` is falsy.
если ты считаешьBigInt
, количество примитивных типов в JavaScript изменилось с 6 до 7.
- Boolean
- Null
- Undefined
- Number
- String
- Symbol (new in ECMAScript 2015)
- BigInt (new in future ECMAScript)
операция
BigInt
Поддерживает наиболее часто используемые операторы,+
, -
, *
, /
, %
, а также**
.
|, &, <<, >>, ^
производительность такжеNumber
последовательный по типу.
унарный оператор-
представляет собой отрицательное число, но+
Не может использоваться для представления положительных чисел. Потому что в webAssembly (asm.js)+x
всегда означаетNumber
или необычные обстоятельства.
Также нельзя смешиватьBigInt
а такжеNumber
Рассчитайте, например, в следующем результате выброс исключение:
1 + 1n
// Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
Так как их нельзя смешиватьBigInt
а такжеNumber
, вы не можете избавиться от необходимости помещать весь код вNumber
использовать обаBigInt
заменять. Это зависит от ситуации, если число может стать очень большим, решите использоватьBigInt
.
API
-
BigInt()
Number()
BigInt
Типы.BigInt(1) // 1n BigInt(1.5) // RangeError BigInt('1.5') // SyntaxError
-
BIGINT64ARRAY и BIGUINT64ARRAY
в то же время
BigInt
64-битные целые числа со знаком и без знака также могут быть представлены точно, поэтому есть два новых TypedArray, а именно BigInt64Array и BigUint64Array.const view = new BigInt64Array(4); // → [0n, 0n, 0n, 0n] view.length; // → 4 view[0]; // → 0n view[0] = 42n; view[0]; // → 42n
ECMAScript TC39 Прогресс
В настоящее время определены новые возможности ES2019, см.Twitter -New JavaScript features in ES2019Без BigInt, как показано ниже:
➡️ Array#{flat,flatMap}
➡️ Object.fromEntries
➡️ String#{trimStart,trimEnd}
➡️ Symbol#description
➡️ try { } catch {} // optional binding
➡️ JSON ⊂ ECMAScript
➡️ well-formed JSON.stringify
➡️ stable Array#sort
➡️ revised Function#toString
Также доступно на githubtc39 завершенный драфтвидел в.
BigInt
в настоящее время вЭтап 3, если проблема не большая, ее надо включить в ES2020.
Поддержка и полифилл
В настоящее время (201902) поддержка браузеров не идеальна, только Chrome поддерживает лучше, а другие браузеры не поддерживают хорошо. В отличие от других новых функций JavaScript, BigInt плохо компилируется в ES5. Поскольку BigInt изменяет рабочее поведение операторов, это поведение не может быть напрямую преобразовано полифиллами.
Но можно использовать библиотекуthe JSBI libraryДля реализации Bigint. JSBI — это дизайн и реализация Bigint в V8 и Chrome, функция совместима с браузером, а синтаксис немного отличается:
import JSBI from './jsbi.mjs';
const max = JSBI.BigInt(Number.MAX_SAFE_INTEGER);
const two = JSBI.BigInt('2');
const result = JSBI.add(max, two);
console.log(result.toString());
// → '9007199254740993'
Как только BigInt станет встроенной поддержкой для всех браузеров, можно будет использовать плагины.babel-plugin-transform-jsbi-to-bigintУдалите JSBI в собственный синтаксис BigInt. Например, приведенный выше код преобразуется в:
const max = BigInt(Number.MAX_SAFE_INTEGER);
const two = 2n;
const result = max + two;
console.log(result);
// → '9007199254740993'
Поддержка TypeScript
Tymdercript 3.2 был добавленBigInt
target: esnext
Вот и все. Примеры использования следующие:
let foo: bigint = BigInt(100); // the BigInt function
let bar: bigint = 100n; // a BigInt literal
// *Slaps roof of fibonacci function*
// This bad boy returns ints that can get *so* big!
function fibonacci(n: bigint) {
let result = 1n;
for (let last = 0n, i = 0n; i < n; i++) {
const current = result;
result += last;
last = current;
}
return result;
}
fibonacci(10000n)
резюме
Если вы уверены, что ваша страница работает только в последней версии Chrome, смело используйте ее прямо сейчас.BigInt
Теперь обрабатывайте большие данные более элегантно и эффективно. Если вам нужна поддержка в других браузерах, вы можете использоватьJSBIЭта библиотека, поза скинуть ее в будущем, тоже очень элегантна.
Приятно видеть, что JavaScript становится все более и более надежным. Благодаря мощной сквозной вычислительной мощности и развитию искусственного интеллекта вскоре можно будет использовать этоBigInt
характерная черта.