[Javascript] BigInt
JS BigInt, JavaScript BigInt, 임의 정밀도 정수
정의
BigInt 는 임의 정밀도 정수. Number.MAX_SAFE_INTEGER (2^53 - 1) 를 넘어가는 정수를 정확히 표현. ES2020 도입.
const big = 12345678901234567890n; // 끝에 'n'
const fromCtor = BigInt('12345678901234567890');
typeof big // 'bigint'
사용 상황
| 상황 | 권장 타입 |
|---|---|
| 64-bit 정수 ID (DB의 BIGINT 컬럼) | BigInt 또는 string |
| 금융 계산 (cent 단위 정수) | BigInt |
| 암호화 (RSA, ECC 큰 소수 연산) | BigInt |
| 비트 연산 (64-bit 이상) | BigInt |
| 일반 정수 연산 (2^53 미만) | Number |
| JSON 인터페이스 경계 | string |
| 부동소수점 계산 | Number |
왜 필요한가
9007199254740992 + 1 // 9007199254740992 ❌ (정확도 손실)
9007199254740992n + 1n // 9007199254740993n ✓
큰 ID, 암호화, 정밀 산술, 통화 (cent 기반 정수) 에 안전.
사용
const a = 10n;
const b = 20n;
a + b // 30n
a * b // 200n
a / b // 0n (정수 나눗셈)
a ** 3n // 1000n
a < b // true
a === b - 10n // true
함정: number 와 혼합 금지
1n + 1 // ❌ TypeError: Cannot mix BigInt and other types
1n + 1n // 2n
1n + BigInt(1) // 2n
Number(1n) + 1 // 2
같은 타입끼리만 산술 가능. 명시적 변환 필요.
비교는 가능
1n == 1 // true (== 는 변환 허용)
1n === 1 // false (=== 는 엄격)
1n < 2 // true (관계 연산자는 OK)
BigInt → Number
Number(123n) // 123
Number(12345678901234567890n) // 12345678901234568000 (정확도 손실!)
작은 BigInt 만 Number 변환 안전.
JSON 호환성
JSON.stringify({ id: 1n }) // ❌ TypeError
JSON.stringify({ id: '1' }) // 우회: string 으로
JSON 표준은 BigInt 미지원. 직렬화는 문자열로.
// BigInt → JSON (string)
JSON.stringify({ id: 1234n }, (k, v) =>
typeof v === 'bigint' ? v.toString() : v)
// '{"id":"1234"}'
// JSON → BigInt (reviver)
JSON.parse(text, (k, v) =>
k === 'id' ? BigInt(v) : v)
자주 쓰는 사례
1. 큰 ID 처리
const userId = BigInt('9223372036854775807'); // 64-bit max
DB 의 BIGINT 컬럼 (PostgreSQL bigserial 등) 매칭.
2. 정밀 계산
// 통화: cent 단위로 정수 처리
const balance = 100_00n; // $100.00 = 10000 cent
const transfer = 50_00n;
const remaining = balance - transfer;
3. 비트 연산 (큰 정수)
const flags = 0n;
const FLAG_ADMIN = 1n << 63n; // 64-bit 비트 위치
flags | FLAG_ADMIN
4. 암호화 모듈러 거듭제곱
// RSA 등에서 사용하는 모듈러 거듭제곱
function modPow(base, exp, mod) {
let result = 1n;
base = base % mod;
while (exp > 0n) {
if (exp % 2n === 1n) result = (result * base) % mod;
exp = exp / 2n;
base = (base * base) % mod;
}
return result;
}
modPow(2n, 10n, 1000n); // 24n
Math 함수와 호환 안 됨
Math.abs(-5n) // ❌ TypeError
// 직접 처리
const abs = (x) => x < 0n ? -x : x;
abs(-5n) // 5n
Math.* 함수는 BigInt 미지원.
Number vs BigInt 선택
flowchart TD
Q["정수가 2의 53승 - 1을 넘을 수 있는가?"]
Q -->|"yes"| B1["BigInt 사용"]
Q -->|"no"| N1["Number 충분"]
B1 --> J["JSON 직렬화 필요?"]
J -->|"yes"| S["string 으로 변환 후 저장"]
J -->|"no"| BI2["BigInt 그대로 사용"]
N1 --> F["부동소수점 필요?"]
F -->|"yes"| NUM["Number float64"]
F -->|"no"| NUM2["Number 정수 범위 내"]
| 시나리오 | 권장 |
|---|---|
| 일반 정수 (< 2^53) | Number |
| 큰 ID | BigInt 또는 string |
| 정밀 산술 (통화) | BigInt (정수 단위) |
| 부동소수점 | Number |
| 비트 연산 (64-bit+) | BigInt |
| JSON 인터페이스 | string |
BigInt 와 TypeScript
TypeScript 는 bigint 타입을 기본 지원.
const id: bigint = 123n;
const huge: bigint = BigInt('9007199254740993');
// 함수 시그니처
function factorial(n: bigint): bigint {
return n <= 1n ? 1n : n * factorial(n - 1n);
}
// JSON 경계에서는 string 으로
type SafeId = bigint | string;
bigint 와 number 는 TypeScript 에서도 자동 변환이 안 된다. 명시적 Number(big) / BigInt(num) 필요.
성능 고려사항
BigInt 연산은 Number 보다 느리다. 특히 곱셈, 나눗셈에서 차이가 크다.
// 루프 카운터에 BigInt 사용하면 불필요한 오버헤드
for (let i = 0n; i < 1000n; i++) { /* 느림 */ }
for (let i = 0; i < 1000; i++) { /* 빠름 */ }
- BigInt 는 Number 보다 3-10배 느린 연산 속도 (엔진에 따라 차이)
- 암호화나 임의 정밀도 연산이 아니라면 Number 범위 내에서 처리
BigInt를 Number 범위 내 값에 쓰는 것은 불필요한 타입 복잡도
함정
1. 리터럴 표기
1n // ✓
0o10n // ✓ (8진 BigInt)
0x10n // ✓ (16진)
1_000_000n // ✓ (separator)
1.5n // ❌ SyntaxError (BigInt 는 정수만)
2. Math.pow
2n ** 100n // BigInt 거듭제곱 (정확)
Math.pow(2, 100) // 1.2676506002282294e+30 (Number, 정확도 손실)
3. Array, Set 의 키
new Set([1n, 1]) // {1n, 1} (다른 키로 취급)
4. 조건문에서 0n 은 falsy
Boolean(0n) // false
Boolean(1n) // true
if (0n) { /* 실행 안 됨 */ }
Number 의 0 과 동일하게 falsy. 혼합 비교 시 주의.
관련 위키
이 글의 용어 (3개)
- [Javascript] 타입 변환 / 강제 변환javascript
- 정의 JavaScript 의 암묵적 형변환 (coercion). 연산자가 양쪽 피연산자의 타입을 자동으로 맞춘다. 명시적 변환과 구분. 3 가지 강제 변환 1. ToString …
- [Javascript] JSONjavascript
- 정의 JSON (JavaScript Object Notation) 은 데이터 교환 형식. JS 의 객체 리터럴과 비슷하지만 엄격한 문법. - : JS 값 → JSON 문자열 - …
- [Javascript] Numberjavascript
- 정의 JavaScript 의 는 IEEE 754 double-precision float (64-bit). 정수와 실수를 같은 타입으로 표현. 정수 안전 범위는 . IEEE 75…
💬 댓글