Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «BigInt проти Number». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`BigInt` це окремий числовий тип для цілих чисел довільної довжини, який не має обмеження `Number.MAX_SAFE_INTEGER` (2^53 - 1) і тому не втрачає точність на великих значеннях.** Звичайний `Number` зберігається як 64-бітне число з рухомою крапкою (IEEE 754), тож після 2^53 - 1 сусідні цілі «злипаються». Літерал `BigInt` пишеться з суфіксом `n` або створюється через `BigInt()`, не підтримує дроби і не змішується з `Number` в одному виразі. ```javascript const num = 9007199254740991; console.log(num + 2); // 9007199254740992, точність втрачено const big = 9007199254740991n; console.log(big + 2n); // 9007199254740993n, точно ``` **Ключове:** `BigInt` беруть там, де важлива точна цілочисельна арифметика (великі ID, криптографія, блокчейн, гроші), а `Number` залишають для звичайних обчислень із дробами.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`BigInt` це спеціальний числовий тип JavaScript, який дозволяє працювати з цілими числами довільної довжини, без обмеження 2^53 - 1.** Значення створюється додаванням `n` у кінці числа або викликом функції `BigInt()`. ```javascript const big = 123456789012345678901234567890n; const big2 = BigInt("123456789012345678901234567890"); ``` ## Теорія ### TL;DR - Усі звичайні числа в JavaScript мають тип `Number` і зберігаються у форматі IEEE 754 (64-бітне число з рухомою крапкою). - Точно представляти цілі можна лише до `Number.MAX_SAFE_INTEGER === 9007199254740991` (2^53 - 1), далі починається втрата точності. - `BigInt` знімає це обмеження: довжина цілого числа обмежена лише пам'яттю. - Створюється літералом із суфіксом `n` (`10n`) або функцією `BigInt(10)`, `BigInt("9007199254740995")`. - Дробів не підтримує: `BigInt(1.5)` кидає `TypeError`, а ділення `5n / 2n` відкидає дробову частину. - Не змішується з `Number` в арифметиці, не працює з `Math` і не серіалізується через `JSON.stringify()`. ### Швидкий приклад ```javascript const a = 10n; // літерал const b = BigInt(10); // через функцію const c = BigInt("9007199254740995"); // з рядка console.log(a + b); // 20n console.log(c + 1n); // 9007199254740996n ``` ### Проблема звичайних чисел У JavaScript усі звичайні числа мають тип `Number` і зберігаються у форматі **IEEE 754 (64-бітне число з рухомою крапкою)**. Це означає, що мова може точно представляти цілі числа лише до: ```javascript Number.MAX_SAFE_INTEGER === 9007199254740991; // 2^53 - 1 ``` Якщо число більше, починається втрата точності: ```javascript const num = 9007199254740991; console.log(num + 1); // 9007199254740992, коректно console.log(num + 2); // 9007199254740992, помилка ``` > Числа «злиплися»: рушій уже не може відрізнити `+1` від `+2`, бо сусідні цілі в цьому діапазоні не мають окремого представлення. `BigInt` вирішує саме цю проблему: ```javascript const big = 9007199254740991n; console.log(big + 1n); // 9007199254740992n console.log(big + 2n); // 9007199254740993n, точно ``` ### Як створити BigInt Є три способи, і жоден з них не приймає дробів: ```javascript const a = 10n; // літерал const b = BigInt(10); // через функцію const c = BigInt("9007199254740995"); // з рядка ``` ```javascript BigInt(1.5); // TypeError: Cannot convert 1.5 to a BigInt ``` ### Арифметика з BigInt Підтримуються базові операції, але всі вони цілочисельні: ```javascript const x = 5n; const y = 2n; console.log(x + y); // 7n console.log(x - y); // 3n console.log(x * y); // 10n console.log(x / y); // 2n, дробова частина відкидається console.log(x ** y); // 25n ``` > Ділення завжди повертає ціле число, залишок просто відкидається (`5n / 2n` це `2n`, а не `2.5`). `Number` і `BigInt` не можна змішувати в одному арифметичному виразі: ```javascript const big = 10n; const num = 5; console.log(big + num); // TypeError: Cannot mix BigInt and other types ``` Потрібне явне приведення типу: ```javascript console.log(big + BigInt(num)); // 15n // або console.log(Number(big) + num); // 15 ``` Порівняння, на відміну від арифметики, працює: при нестрогому порівнянні тип приводиться автоматично. ```javascript 10n == 10; // true, нестроге порівняння 10n === 10; // false, строге порівняння, типи різні 10n < 20; // true ``` Функції `Math` з `BigInt` несумісні: ```javascript Math.sqrt(4n); // TypeError: Cannot convert a BigInt value to a number ``` За потреби значення спочатку приводять: `Math.sqrt(Number(4n))`, пам'ятаючи, що на дуже великих числах таке приведення знову втратить точність. ### Number проти BigInt | Особливість | `Number` | `BigInt` | | --- | --- | --- | | Тип | число з рухомою крапкою | ціле число довільної довжини | | Максимальна точність | до 2^53 - 1 | необмежена | | Підтримка дробів | так | ні | | Операції | стандартні | стандартні, але тільки цілочисельні | | Сумісність | скрізь | з 2020 року | | Використання з `JSON` | так | ні, `JSON.stringify()` кидає помилку | | Приведення типів | сумісний з усім | треба приводити явно | | Коли брати | звичайні числа і дроби | дуже великі цілі | ### Де застосовують BigInt Зберігання великих ідентифікаторів, наприклад з бази даних, де 64-бітний `id` не вміщується в безпечний діапазон `Number`: ```javascript const userId = 183748917238479182374981273n; ``` Криптографія, блокчейн і фінанси, де округлення неприпустиме: ```javascript const balance = 999999999999999999999999999n; const transfer = 250000000000000000000n; console.log(balance - transfer); // рахує точно ``` Сюди ж належать лічильники з дуже великими значеннями, часові мітки в наносекундах і будь-яка робота з цілими числами, де помилка на одиницю неприпустима. ### Типові помилки - **Змішування типів в арифметиці.** `10n + 5` це `TypeError`, а не `15n`. Приводьте явно: `10n + BigInt(5)` або `Number(10n) + 5`. - **Очікування дробового ділення.** `7n / 2n` дає `3n`, залишок відкидається мовчки, без жодної помилки. - **Спроба створити `BigInt` з дробу.** `BigInt(1.5)` кидає `TypeError`, спершу треба округлити: `BigInt(Math.trunc(1.5))`. - **`JSON.stringify()` з `BigInt` у структурі.** Кидає `TypeError: Do not know how to serialize a BigInt`, тому такі значення передають рядком: `String(id)`. - **Плутанина `==` і `===`.** `10n == 10` це `true`, але `10n === 10` це `false`, бо типи різні. - **Виклик `Math` з `BigInt`.** `Math.max(1n, 2n)` і `Math.sqrt(4n)` кидають `TypeError`. - **Використання `BigInt` там, де він не потрібен.** Він повільніший за `Number` і не підтримує дробів, тож для звичайних обчислень залишайте `Number`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.