Skip to content

Commit df35bee

Browse files
authored
Merge pull request #813 from pakhuta/add-chapter-of-bigInt
Add translation of BigInt chapter
2 parents 5e37662 + cf9663e commit df35bee

File tree

3 files changed

+158
-7
lines changed

3 files changed

+158
-7
lines changed

1-js/02-first-steps/05-types/article.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,25 @@ n = 12.345;
6262

6363
Подробнее о работе с числами мы поговорим в главе <info:number>.
6464

65+
## BigInt
66+
67+
В JavaScript тип "number" не может содержать числа больше, чем <code>2<sup>53</sup></code> (или меньше, чем <code>-2<sup>53</sup></code> для отрицательных). Это техническое ограничение вызвано их внутренним представлением. <code>2<sup>53</sup></code> - это достаточно большое число, состоящее из 16 цифр, поэтому чаще всего проблем не возникает. Но иногда нам нужны действительно гигантские числа, например в криптографии или при использовании метки времени ("timestamp") с микросекундами.
68+
69+
Тип `BigInt` был добавлен в JavaScript, чтобы дать возможность работать с целыми числами произвольной длины.
70+
71+
Чтобы создать значение типа `BigInt`, необходимо добавить `n` в конец числового литерала:
72+
73+
```js
74+
// символ "n" в конце означает, что это BigInt
75+
const bigInt = 1234567890123456789012345678901234567890n;
76+
```
77+
78+
Так как `BigInt` числа нужны достаточно редко, мы рассмотрим их в отдельной главе <info:bigint>.
79+
80+
```smart header="Поддержка"
81+
В данный момент `BigInt` поддерживается только в браузерах Firefox и Chrome, но не поддерживается в Safari/IE/Edge.
82+
```
83+
6584
## Строка
6685

6786
Строка (`string`) в JavaScript должна быть заключена в кавычки.
@@ -198,6 +217,8 @@ typeof undefined // "undefined"
198217

199218
typeof 0 // "number"
200219

220+
typeof 10n // "bigint"
221+
201222
typeof true // "boolean"
202223

203224
typeof "foo" // "string"
@@ -226,9 +247,10 @@ typeof alert // "function" (3)
226247

227248
## Итого
228249

229-
В JavaScript есть 7 основных типов.
250+
В JavaScript есть 8 основных типов.
230251

231-
- `number` для любых чисел: целочисленных или чисел с плавающей точкой.
252+
- `number` для любых чисел: целочисленных или чисел с плавающей точкой, целочисленные значения ограничены диапазоном ±2<sup>53</sup>.
253+
- `bigint` для целых чисел произвольной длины.
232254
- `string` для строк. Строка может содержать один или больше символов, нет отдельного символьного типа.
233255
- `boolean` для `true`/`false`.
234256
- `null` для неизвестных значений -- отдельный тип, имеющий одно значение `null`.

1-js/05-data-types/02-number/article.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# Числа
22

3-
Все числа в JavaScript хранятся в 64-битном формате [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985), который также называют "числа с плавающей точкой двойной точности" (double precision floating point numbers).
3+
В современном JavaScript существует два типа чисел:
4+
1. Обычные числа в JavaScript хранятся в 64-битном формате [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985), который также называют "числа с плавающей точкой двойной точности" (double precision floating point numbers). Это числа, которые мы будем использовать чаще всего. Мы поговорим о них в этой главе.
5+
2. `BigInt` числа дают возможность работать с целыми числами произвольной длины. Они нужны достаточно редко и используются в случаях, когда необходимо работать со значениями более чем <code>2<sup>53</sup></code> или менее чем <code>-2<sup>53</sup></code>. Так как `BigInt` числа нужны достаточно редко, мы рассмотрим их в отдельной главе <info:bigint>.
46

5-
Давайте глубже изучим, как работать с числами в JavaScript.
7+
В данной главе мы рассмотрим только первый тип чисел: числа типа `number`. Давайте глубже изучим, как с ними работать в JavaScript.
68

79
## Способы записи числа
810

@@ -407,10 +409,10 @@ alert( parseInt('2n9c', 36) ); // 123456
407409

408410
## Итого
409411

410-
Чтобы писать большие числа:
412+
Чтобы писать числа с большим количеством нулей:
411413

412-
- Используйте краткую форму записи больших чисел - `"e"`, с указанным количеством нулей. Например: `123e6` это `123` с 6-ю нулями.
413-
- Отрицательное число после `"e"` приводит к делению числа на 1 с указанным количеством нулей.
414+
- Используйте краткую форму записи чисел - `"e"`, с указанным количеством нулей. Например: `123e6` это `123` с 6-ю нулями `123000000`.
415+
- Отрицательное число после `"e"` приводит к делению числа на 1 с указанным количеством нулей. Например: `123e-6` это `0.000123` (`123` миллионная).
414416

415417
Для других систем счисления:
416418

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# BigInt
2+
3+
[recent caniuse="bigint"]
4+
5+
`BigInt` - это специальный числовой тип, который предоставляет возможность работать с целыми числами произвольной длины.
6+
7+
Чтобы создать значение типа `BigInt`, необходимо добавить `n` в конец числового литерала или вызвать функцию `BigInt`, которая создаст число типа `BigInt` из переданного аргумента. Аргументом может быть число, строка и др.
8+
9+
```js
10+
const bigint = 1234567890123456789012345678901234567890n;
11+
12+
const sameBigint = BigInt("1234567890123456789012345678901234567890");
13+
14+
const bigintFromNumber = BigInt(10); // то же самое, что и 10n
15+
```
16+
17+
## Математические операторы
18+
19+
`BigInt` может использоваться как обычные числа, к примеру:
20+
21+
```js run
22+
alert(1n + 2n); // 3
23+
24+
alert(5n / 2n); // 2
25+
```
26+
27+
Обратите внимание: операция деления `5/2` возвращает округлённый результат, без дробной части. Все операции с числами типа `bigint` возвращают `bigint`.
28+
29+
В математических операциях мы не можем смешивать `bigint` и обычные числа:
30+
31+
```js run
32+
alert(1n + 2); // Error: Cannot mix BigInt and other types
33+
```
34+
35+
Мы должны явно их конвертировать: используя либо `BigInt()`, либо `Number()`, например:
36+
37+
```js run
38+
let bigint = 1n;
39+
let number = 2;
40+
41+
// конвертируем number в bigint
42+
alert(bigint + BigInt(number)); // 3
43+
44+
// конвертируем bigint в number
45+
alert(Number(bigint) + number); // 3
46+
```
47+
48+
Конвертирование bigint в число всегда происходит неявно и без генерации ошибок, но если значение bigint слишком велико и не подходит под тип number, то дополнительные биты будут отброшены, так что следует быть осторожными с такими преобразованиями.
49+
50+
````smart header="К `BigInt` числам нельзя применить унарный оператор `+`"
51+
Унарный оператор `+value` является хорошо известным способом конвертировать `value` в число.
52+
53+
Данный оператор не поддерживается при работе с `BigInt` числами.
54+
```js run
55+
let bigint = 1n;
56+
57+
alert( +bigint ); // SyntaxError: Unexpected identifier
58+
```
59+
````
60+
61+
## Операции сравнения
62+
63+
Операции сравнения, такие как `<`, `>`, работают с bigint и обычными числами как обычно:
64+
65+
```js run
66+
alert( 2n > 1n ); // true
67+
68+
alert( 2n > 1 ); // true
69+
```
70+
71+
Пожалуйста, обратите внимание, что обычные и bigint числа принадлежат к разным типам, они могут быть равны только при нестрогом сравнении `==`:
72+
73+
```js run
74+
alert( 1 == 1n ); // true
75+
76+
alert( 1 === 1n ); // false
77+
```
78+
79+
## Логические операции
80+
81+
В `if` или любом другом логическом операторе bigint число ведёт себя как обычное число.
82+
83+
К примеру, в `if` bigint `0n` преобразуется в `false`, другие значения преобразуются в `true`:
84+
85+
```js run
86+
if (0n) {
87+
// никогда не выполнится
88+
}
89+
```
90+
91+
Логические операторы `||`, `&&` и другие также работают с bigint числами как с обычными числами:
92+
93+
```js run
94+
alert( 1n || 2 ); // 1
95+
96+
alert( 0n || 2 ); // 2
97+
```
98+
99+
## Полифилы
100+
101+
Создание полифила для `BigInt` - достаточно непростая задача. Причина в том, что многие операторы в JavaScript, такие как `+`, `-` и др., ведут себя по-разному с bigint по сравнению с обычными числами.
102+
103+
К примеру, деление bigint числа всегда возвращает bigint (округлённое при необходимости).
104+
105+
Чтобы эмулировать такое поведение, полифил должен будет проанализировать код и заменить все такие операторы на свои вызовы. Такая реализация будет тяжеловесной, не очень хорошей с точки зрения производительности.
106+
107+
Вот почему на данный момент нет хорошо реализованного полифила.
108+
109+
Существует обратное решение, предложеное разработчиками библиотеки [https://github.com/GoogleChromeLabs/jsbi](JSBI).
110+
111+
Эта библиотека реализует большие числа, используя собственные методы. Мы можем использовать их вместо встроенных bigint
112+
113+
| Операция | Встроенный BigInt | JSBI |
114+
|-----------|-----------------|------|
115+
| Создание из `number` | `a = BigInt(789)` | `a = JSBI.BigInt(789)` |
116+
| Сложение | `c = a + b` | `c = JSBI.add(a, b)` |
117+
| Вычитание | `c = a - b` | `c = JSBI.subtract(a, b)` |
118+
| ... | ... | ... |
119+
120+
...А затем использовать полифил (плагин Babel) для замены вызовов JSBI на встроенные `Bigint` для браузеров, которые их поддерживают.
121+
122+
Другими словами, данный подход предлагает использовать JSBI вместо встроенных bigint. JSBI внутри себя работает с числами как с bigint, эмулирует их с соблюдением всех требований спецификации. Таким образом, мы можем выполнять JSBI-код в интерпретаторах, которые не поддерживают `Bigint`, а для тех, которые поддерживают - полифил преобразует вызовы в обычные `Bigint`.
123+
124+
## Ссылки
125+
126+
- MDN: [BigInt](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/BigInt).
127+
- Спецификация: [BigInt](https://tc39.es/ecma262/#sec-bigint-objects).

0 commit comments

Comments
 (0)