Skip to content

BigInt #238

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 20, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 43 additions & 43 deletions 1-js/99-js-misc/05-bigint/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,129 +2,129 @@

[recent caniuse="bigint"]

`BigInt` is a special numeric type that provides support for integers of arbitrary length.
`BigInt` – це спеціальний числовий тип, який забезпечує підтримку цілих чисел довільної довжини.

A bigint is created by appending `n` to the end of an integer literal or by calling the function `BigInt` that creates bigints from strings, numbers etc.
Bigint створюється шляхом додавання `n` до кінця цілочисельного літералу або викликом функції `BigInt`, яка створює великі числа з рядків, чисел тощо.

```js
const bigint = 1234567890123456789012345678901234567890n;

const sameBigint = BigInt("1234567890123456789012345678901234567890");

const bigintFromNumber = BigInt(10); // same as 10n
const bigintFromNumber = BigInt(10); // те саме що і 10n
```

## Math operators
## Математичні оператори

`BigInt` can mostly be used like a regular number, for example:
`BigInt` можна використовувати як звичайне число, наприклад:

```js run
alert(1n + 2n); // 3

alert(5n / 2n); // 2
```

Please note: the division `5/2` returns the result rounded towards zero, without the decimal part. All operations on bigints return bigints.
Зверніть увагу: поділ `5/2` повертає результат, округлений до нуля, без десяткової частини. Усі операції над великими числами повертають великі числа.

We can't mix bigints and regular numbers:
Ми не можемо змішувати великі та звичайні числа:

```js run
alert(1n + 2); // Error: Cannot mix BigInt and other types
```

We should explicitly convert them if needed: using either `BigInt()` or `Number()`, like this:
Ми повинні явно конвертувати їх, якщо потрібно: використовуючи `BigInt()` або `Number()`, наприклад:

```js run
let bigint = 1n;
let number = 2;

// number to bigint
// число у велике число
alert(bigint + BigInt(number)); // 3

// bigint to number
// велике число у число
alert(Number(bigint) + number); // 3
```

The conversion operations are always silent, never give errors, but if the bigint is too huge and won't fit the number type, then extra bits will be cut off, so we should be careful doing such conversion.
Операції перетворення завжди безшумні, ніколи не дають помилок, але якщо величе число занадто велике і не відповідає типу числа, то зайві біти будуть відрізані, тому ми повинні бути обережними, виконуючи таке перетворення.

````smart header="The unary plus is not supported on bigints"
The unary plus operator `+value` is a well-known way to convert `value` to a number.
````smart header="Унарний плюс не підтримується на великих числах"
Оператор унарний плюс `+value` є добре відомим способом перетворення `value` у число.

In order to avoid confusion, it's not supported on bigints:
Щоб уникнути плутанини, він не підтримується на великих числах:
```js run
let bigint = 1n;

alert( +bigint ); // error
alert( +bigint ); // помилка
```
So we should use `Number()` to convert a bigint to a number.
Тому ми повинні використовувати `Number()`, щоб перетворити велике число в число.
````

## Comparisons
## Порівняння

Comparisons, such as `<`, `>` work with bigints and numbers just fine:
Порівняння, такі як `<`, `>`, чудово працюють з великими та числами:

```js run
alert( 2n > 1n ); // true

alert( 2n > 1 ); // true
```

Please note though, as numbers and bigints belong to different types, they can be equal `==`, but not strictly equal `===`:
Зверніть увагу, оскільки числа та великі числа мають різні типи, вони можуть бути рівними `==`, але не строго рівними `===`:

```js run
alert( 1 == 1n ); // true

alert( 1 === 1n ); // false
```

## Boolean operations
## Булеві операції

When inside `if` or other boolean operations, bigints behave like numbers.
Всередині `if` або інших логічних операцій великі числа поводяться як числа.

For instance, in `if`, bigint `0n` is falsy, other values are truthy:
Наприклад, у `if` величе число `0n` є хибним, інші значення є істинними:

```js run
if (0n) {
// never executes
// ніколи не виконається
}
```

Boolean operators, such as `||`, `&&` and others also work with bigints similar to numbers:
Логічні оператори, такі як `||`, `&&` та інші також працюють з великими числами, подібно до чисел:

```js run
alert( 1n || 2 ); // 1 (1n is considered truthy)
alert( 1n || 2 ); // 1 (1n вважається істинним)

alert( 0n || 2 ); // 2 (0n is considered falsy)
alert( 0n || 2 ); // 2 (0n вважається хибним)
```

## Polyfills
## Поліфіли

Polyfilling bigints is tricky. The reason is that many JavaScript operators, such as `+`, `-` and so on behave differently with bigints compared to regular numbers.
Поліфілення великих чисел є складним. Причина в тому, що багато операторів в JavaScript, таких як `+`, `-` тощо, поводяться по-різному з великими числами порівняно зі звичайними числами.

For example, division of bigints always returns a bigint (rounded if necessary).
Наприклад, поділ великих чисел завжди повертає велике число (за потреби округляється).

To emulate such behavior, a polyfill would need to analyze the code and replace all such operators with its functions. But doing so is cumbersome and would cost a lot of performance.
Щоб емулювати таку поведінку, поліфіл має проаналізувати код і замінити всі такі оператори своїми функціями. Але це громіздко і буде коштувати великої жертви в продуктивності.

So, there's no well-known good polyfill.
Отже, добре відомого хорошого поліфілу не існує.

Although, the other way around is proposed by the developers of [JSBI](https://github.com/GoogleChromeLabs/jsbi) library.
Проте, розробники бібліотеки [JSBI](https://github.com/GoogleChromeLabs/jsbi) пропонують рішення.

This library implements big numbers using its own methods. We can use them instead of native bigints:
Ця бібліотека реалізує підтрику великих чисел, використовуючи власні методи. Ми можемо використовувати їх замість нативних великих чисел:

| Operation | native `BigInt` | JSBI |
| Операція | нативний `BigInt` | JSBI |
|-----------|-----------------|------|
| Creation from Number | `a = BigInt(789)` | `a = JSBI.BigInt(789)` |
| Addition | `c = a + b` | `c = JSBI.add(a, b)` |
| Subtraction | `c = a - b` | `c = JSBI.subtract(a, b)` |
| Створення from Number | `a = BigInt(789)` | `a = JSBI.BigInt(789)` |
| Додавання | `c = a + b` | `c = JSBI.add(a, b)` |
| Віднимання | `c = a - b` | `c = JSBI.subtract(a, b)` |
| ... | ... | ... |

...And then use the polyfill (Babel plugin) to convert JSBI calls to native bigints for those browsers that support them.
...А потім скористайтеся поліфілом (плагін для Babel), щоб перетворити виклики JSBI на нативні великі числа для тих браузерів, які їх підтримують.

In other words, this approach suggests that we write code in JSBI instead of native bigints. But JSBI works with numbers as with bigints internally, emulates them closely following the specification, so the code will be "bigint-ready".
Іншими словами, цей підхід припускає, що ми пишемо код на JSBI замість нативних великих чисел. Але JSBI всередині працює з числами як із великими числами, емулює їх відповідно до специфікації, тож код буде «готовий до великих чисел».

We can use such JSBI code "as is" for engines that don't support bigints and for those that do support - the polyfill will convert the calls to native bigints.
Ми можемо використовувати такий код JSBI «як є» для двигунців, які не підтримують великі числа, а для тих, які підтримують - поліфіл конвертуватиме виклики в нативні великі числа.

## References
## Посилання

- [MDN docs on BigInt](mdn:/JavaScript/Reference/Global_Objects/BigInt).
- [Specification](https://tc39.es/ecma262/#sec-bigint-objects).
- [Документація на MDN про великі числа](mdn:/JavaScript/Reference/Global_Objects/BigInt).
- [Специфікація](https://tc39.es/ecma262/#sec-bigint-objects).