Последний базовый тип данных JS: BigInt

программист JavaScript

оригинал:woohoo.smashing magazine.com/2019/07/ESS…

Переводчик: Front-end Xiaozhi

Ставь лайк и смотри, поиск в WeChat【Переезд в мир】Обратите внимание на этого человека, который не имеет большого фабричного прошлого, но имеет восходящий и позитивный настрой. эта статьяGitHub GitHub.com/QQ449245884…Он был включен, статьи были классифицированы, и многие мои документы и учебные материалы были систематизированы.

Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.

BigIntЦель типа данных — сравнитьNumberБолее широкий диапазон целочисленных значений, поддерживаемых типом данных. Возможность представления целых чисел с произвольной точностью особенно важна при выполнении математических операций над большими целыми числами. использоватьBigInt, целочисленное переполнение больше не будет проблемой.

Кроме того, более точные метки времени, большие целочисленные идентификаторы и т. д. можно безопасно использовать без использования обходных путей.BigIntВ настоящее время предложение фазы 3, после добавления в спецификацию, это будет второй числовой тип данных JS, а также базовый тип данных JS 8:

  • Boolean
  • Null
  • Undefined
  • Number
  • BigInt
  • String
  • Symbol

В этой статье мы подробно познакомимBigInt, чтобы увидеть, как это разрешается с помощьюNumberтип ограничений.

вопрос

Отсутствие явных целочисленных типов в JS часто сбивает с толку программистов, изучавших другие языки. Многие языки программирования поддерживают несколько числовых типов, таких как float, double, int и double, но это не относится к JS. В JS, согласноIEEE 754-2008Стандартное разрешение, все числа начинаются с64-битная двойная точность с плавающей запятойформатное представление.

Очень большие целые числа, которые не могут быть представлены точно, автоматически округляются в соответствии с этим стандартом. Если быть точным, в JSNumberТипы могут быть безопасно представлены только-9007199254740991 (-(2^53-1))а также9007199254740991(2^53-1)Любое целочисленное значение за пределами этого диапазона может потерять точность.

console.log(9999999999999999);    // → 10000000000000000

Целое число больше, чем наибольшее целое число, которое может представлять тип JS Number, поэтому оно округляется. Случайное округление может поставить под угрозу надежность и безопасность программы. Вот еще один пример:

// 注意最后一位的数字
9007199254740992 === 9007199254740993;    // → true

JS предоставляетNumber.MAX_SAFE_INTEGERконстанта для представления наибольшего безопасного целого числа,Number.MIN_SAFE_INTEGERКонстанта представляет собой наименьшее безопасное целое число:

const minInt = Number.MIN_SAFE_INTEGER;

console.log(minInt);         // → -9007199254740991

console.log(minInt - 5);     // → -9007199254740996

// notice how this outputs the same value as above
console.log(minInt - 4);     // → -9007199254740996

решение

Чтобы обойти эти ограничения, некоторые разработчики JS используют строковый тип для представления больших целых чисел. Например,Twitter APIСтроковая версия идентификатора добавляется к объекту при ответе в формате JSON. Кроме того, было разработано множество библиотек, таких какbignumber.js, для упрощения обработки больших целых чисел.

С BigInt приложениям больше не нужны обходные пути или библиотеки для безопасного представленияNumber.MAX_SAFE_INTEGERа такжеNumber.Min_SAFE_INTEGERкроме целых чисел. Арифметические операции над большими целыми числами теперь можно выполнять в стандартном JS без риска потери точности.

создаватьBigInt, просто добавьте n в конец целого числа. Сравнивать:

console.log(9007199254740995n);    // → 9007199254740995n
console.log(9007199254740995);     // → 9007199254740996

Кроме того, вы можете позвонитьBigInt()Конструктор

BigInt("9007199254740995");    // → 9007199254740995n

BigIntЛитералы также могут быть представлены в двоичном, восьмеричном или шестнадцатеричном виде.

// binary
console.log(0b100000000000000000000000000000000000000000000000000011n);
// → 9007199254740995n

// hex
console.log(0x20000000000003n);
// → 9007199254740995n

// octal
console.log(0o400000000000000003n);
// → 9007199254740995n

// note that legacy octal syntax is not supported
console.log(0400000000000000003n);
// → SyntaxError

Помните, что вы не можете использовать оператор строгого равенства дляBigIntСравните с обычными числами, потому что они разных типов:

console.log(10n === 10);    // → false

console.log(typeof 10n);    // → bigint
console.log(typeof 10);     // → number

Вместо этого вы можете использовать оператор равенства, который выполняет неявное преобразование типа перед обработкой операндов.

console.log(10n == 10);    // → true

За исключением унарного знака плюс (+), все арифметические операторы могут быть использованы дляBigInt

10n + 20n;    // → 30n
10n - 20n;    // → -10n
+10n;         // → TypeError: Cannot convert a BigInt value to a number
-10n;         // → -10n
10n * 20n;    // → 200n
20n / 10n;    // → 2n
23n % 10n;    // → 3n
10n ** 3n;    // → 1000n

const x = 10n;
++x;          // → 11n
--x;          // → 9n

Унарный плюс не поддерживается (+) заключается в том, что некоторые программы могут зависеть от+всегда генерироватьNumberинвариант или выдать исключение. Изменять+поведение также разрушаетasm.jsкод.

Конечно, сBigIntПри использовании вместе с операндами арифметические операторы должны возвращатьBigIntстоимость. Поэтому деление (/) результаты оператора автоматически округляются до ближайшего целого числа. Например:

25 / 10;      // → 2.5
25n / 10n;    // → 2n

неявное преобразование типов

Поскольку неявные преобразования типов могут привести к потере информации, они не разрешены вbigintа такжеNumberсмешанная операция. При смешивании больших целых чисел и чисел с плавающей запятой результирующее значение может не совпадать.BigIntилиNumberточное представление. Рассмотрим следующий пример:

(9007199254740992n + 1n) + 0.5

Результат этого выражения превышаетBigIntа такжеNumberспектр. дробная частьNumberне может быть преобразовано точно вBigInt. больше, чем2^53изBigIntне может быть точно преобразовано в число.

Из-за этого ограничения невозможно использовать смешанныеNumberа такжеBigIntОперанды выполняют арифметические операции. все еще не в состоянииBigIntПередано веб-API и встроенным функциям JS, которые требуютNumberТип чисел. Попробуйте сделать этот отчетTypeErrorошибка

10 + 10n;    // → TypeError
Math.max(2n, 4n, 6n);    // → TypeError

осторожность, реляционные операторы не следуют этому правилу, как в следующем примере:

10n > 5;    // → true

Если вы хотите использоватьBigIntа такжеNumberДля выполнения арифметического вычисления сначала нужно определить, в каком виде должна выполняться операция. Для этого просто позвонитеNumber()илиBigInt()для преобразования операндов:

BigInt(10) + 10n;    // → 20n
// or
10 + Number(10n);    // → 20

когдаBooleanвведите сBigIntКогда типы встречаются,BigIntобрабатывается сNumberаналогично, другими словами, до тех пор, пока не0n,BigIntрассматривается какtruthyЗначение:

if (5n) {
    // 这里代码块将被执行
}

if (0n) {
    // 这里代码块不会执行
}

СортироватьBigIntsа такжеNumbersПри использовании массива неявное преобразование типов не происходит:

const arr = [3n, 4, 2, 1n, 0, -1n];

arr.sort();    // → [-1n, 0, 1n, 2, 3n, 4]

побитовые операторы, такие как|、&、<<、>>а также^правильноBigintоперация иNumberаналогичный. вот несколько примеров

90 | 115;      // → 123
90n | 115n;    // → 123n
90n | 115;     // → TypeError

Конструктор BigInt

Как и другие примитивные типы, его можно создать с помощью конструктораBigInt. Перейти кBigInt()Аргументы будут автоматически преобразованы вBigInt:

BigInt("10");    // → 10n
BigInt(10);      // → 10n
BigInt(true);    // → 1n

Типы данных и значения, которые нельзя преобразовать, вызывают исключения:

BigInt(10.2);     // → RangeError
BigInt(null);     // → TypeError
BigInt("abc");    // → SyntaxError

Вы можете напрямую использовать конструктор для созданияBigIntвыполнять арифметические операции

BigInt(10) * 10n;    // → 100n

При использовании операндов оператора строгого равенства, созданного с помощью конструктораBigintс обычнымBigintобрабатывается аналогично

BigInt(true) === 1n;    // → true

Библиотечные функции

На момент написания этой статьиChrome +67а такжеOpera +54полностью поддерживаюBigIntтип данных. К сожалению,Edgeа такжеSafariЕще не реализовал.FirefoxBigInt не поддерживается по умолчанию, но может использоваться вabout:configгенерал-лейтенантjavascript.options.bigintУстановить какtrueчтобы включить его, последние поддерживаемые случаи можно найти в "Can I use" смотреть.

К сожалению, преобразованиеBigIntявляется чрезвычайно сложным процессом, который приводит к серьезному снижению производительности во время выполнения. Прямой полифиллBigIntТакже невозможно, так как предложение меняет поведение нескольких существующих операторов. В настоящее время лучшим вариантом является использованиеJSBIбиблиотека, этоBigIntРеализация предложения на чистом JS.

Эта библиотека предоставляетBigIntAPI, который ведет себя точно так же. Вот как использовать JSBI:

import JSBI from './jsbi.mjs';

const b1 = JSBI.BigInt(Number.MAX_SAFE_INTEGER);
const b2 = JSBI.BigInt('10');

const result = JSBI.add(b1, b2);

console.log(String(result));    // → '9007199254741001'

использоватьJSBIОдним из преимуществ является то, что когда браузер поддерживает его, нет необходимости переписывать код. Вместо этого вы можете использоватьbabelПлагин автоматически компилирует код JSBI в собственныйBigIntкод.

Суммировать

BigIntэто новый тип данных, используемый, когда целые значения больше, чемNumberДиапазон поддерживает диапазон типов данных. Этот тип данных позволяет нам безопасно выполнять арифметические операции на большом целочисленном, представляющем марки с высоким разрешением, используя большой целочисленный идентификатор и т. Д., Без необходимости использовать библиотеку.

Важно помнить, что вы не можете использоватьNumberа такжеBigIntСмесь операндов выполняет арифметические операции путем явного преобразования одного из типов. Кроме того, по соображениям совместимости не допускаетсяBigIntИспользуйте унарный знак плюс (+) оператор.

общаться с

Статья постоянно обновляется каждую неделю. Вы можете выполнить поиск «Big Move to the World» в WeChat, чтобы прочитать и обновить ее как можно скорее (на одну или две статьи раньше, чем в блоге). Эта статья находится на GitHub.GitHub.com/QQ449245884…Он был включен, и многие мои документы были разобраны. Добро пожаловать в Звезду и совершенство. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Кроме того, обратите внимание на паблик-аккаунт и ответьте в фоновом режиме.Благосостояние, вы можете увидеть преимущества, вы знаете.

Категории