
JavaScript에서 큰 숫자를 다뤄야 하는 경우가 종종 있습니다.
특히 팩토리얼 같은 연산을 할 때 Number 타입의 한계를 경험하게 됩니다.
이 글에서는 JavaScript에서 큰 숫자를 관리하는 방법과 BigInt의 필요성,
그리고 실무에서 BigInt가 사용되는 사례까지 살펴보겠습니다. 💡
1. JavaScript number 타입의 한계 🚧
JavaScript의 기본 숫자 타입인 Number는 64비트 부동소수점(double-precision floating point) 으로 표현됩니다.
JavaScript에서 오차 없이 안전하게 표현할 수 있는 정수의 범위는 다음과 같습니다.
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
하지만 모든 정수를 안전하게 표현할 수 있는 것은 아닙니다.
가장 중요한 제한은 안전한 정수 범위입니다.
즉, 9007199254740991 (약 9경) 이상의 숫자는 정확도가 보장되지 않습니다! 🚨
console.log(9007199254740991 + 1); // 9007199254740992 (정확)
console.log(9007199254740991 + 2); // 9007199254740992 (오차 발생)
위와 같이 MAX_SAFE_INTEGER를 초과하면 연산이 정확하지 않게 됩니다.
그렇다면 이를 해결할 방법은 무엇일까요? 🤔
2. BigInt의 등장 🎉
이러한 number 타입의 한계를 극복하기 위해 JavaScript ES2020에서 새롭게 도입된 타입이 바로 BigInt 입니다.
BigInt는 임의의 정밀도로 정수를 표현할 수 있는 특별한 숫자 타입입니다.
즉, number 타입처럼 표현 범위에 제한이 없어 아무리 큰 정수라도 정확하게 다룰 수 있습니다. 🎉
BigInt는 n을 붙여서 선언하거나 BigInt() 생성자를 이용해 만들 수 있습니다.
const bigNum1 = 9007199254740991n; // BigInt 리터럴
const bigNum2 = BigInt("9007199254740991"); // 문자열을 BigInt로 변환
console.log(bigNum1 + 1n); // 9007199254740992n
BigInt끼리는 일반적인 산술 연산(+, -, *, /, %, **)을 대부분 지원합니다.
다만, number 타입과의 혼합 연산은 명시적인 형 변환 없이는 불가능하며,
부동 소수점 연산은 BigInt에서 지원하지 않습니다.
🔹 BigInt의 특징:
- Number보다 훨씬 큰 정수를 표현 가능
- n을 붙여서 사용하는 타입 (예: 123456789n)
- 부동소수점 연산이 아니라 정수 연산만 가능
하지만 BigInt는 Number와 혼합해서 사용할 수 없습니다. ⛔
console.log(10n + 5); // TypeError: Cannot mix BigInt and other types
BigInt를 Number와 함께 사용하려면 명시적으로 변환해야 합니다.
console.log(Number(10n) + 5); // 15
console.log(BigInt(5) + 10n); // 15n
BigInt의 동작 방식 (내부 구조) ⚙️
number 타입이 고정된 크기의 메모리 공간에 값을 저장하는 반면,
BigInt는 숫자를 문자열처럼 일련의 자릿수로 취급하여 내부적으로 관리합니다.
마치 우리가 손으로 큰 숫자를 계산할 때처럼, 필요한 만큼 메모리 공간을 늘려가며 숫자를 표현할 수 있습니다.
이러한 구조 덕분에 BigInt는 number 타입의 안전한 정수 범위를 초과하는 매우 큰 숫자도 정확하게 저장하고 연산할 수 있습니다.
하지만 이러한 유연성 때문에 BigInt의 연산 속도는 일반적인 number 타입의 연산보다 약간 느릴 수 있습니다.
특히 작은 숫자에 대한 연산에서는 고정 크기의 number 타입이 더 효율적입니다.
3. Number vs BigInt 비교 ⚖️
특징NumberBigInt
최대 정밀도 | 53비트 | 무제한 |
안전한 정수 범위 | ±(2^53 - 1) | 제한 없음 |
소수점 지원 | ✅ | ❌ |
연산 방식 | 부동소수점 | 정수 연산 |
속도 | 상대적으로 빠름 | 느림 |
사용 가능 연산 | +, -, *, /, %, ** | +, -, *, /, %, ** |
✅ 언제 Number를 사용해야 할까?
- 대부분의 연산에서 Number는 충분히 크고 빠름
- 소수점을 다뤄야 하는 경우 BigInt는 사용할 수 없음
✅ 언제 BigInt를 사용해야 할까?
- 팩토리얼 같은 연산 (100! 계산 등)
- 금융 및 암호화 관련 연산 (정확도가 중요한 경우)
- UUID, 블록체인 해시값 등 매우 큰 숫자 관리
4. 실무에서 BigInt가 필요한 경우 💼
✅ 1. 팩토리얼 계산 (100!)
100! (100 팩토리얼)은 일반 Number로 표현할 수 없는 크기입니다.
function factorial(n) {
let result = 1n;
for (let i = 2n; i <= n; i++) {
result *= i;
}
return result;
}
console.log(factorial(100n)); // 엄청 큰 숫자 출력
✅ 2. 금융 및 암호화 연산
금융 계산에서는 1원 단위까지 정확한 연산이 필요할 때가 많습니다. BigInt를 사용하면 정밀도를 유지할 수 있습니다.
const amount1 = BigInt("100000000000000000000"); // 100경 원
const amount2 = BigInt("50000000000000000000"); // 50경 원
console.log(amount1 + amount2); // 150경 원
✅ 3. 블록체인 및 데이터베이스 ID 관리
블록체인의 블록 번호, 해시 값, 대형 ID 값은 BigInt로 관리하는 것이 유리합니다.
const transactionId = BigInt("12839128391283918239812398123");
console.log(transactionId);
5. 결론 🎯
🚀 JavaScript에서 큰 숫자를 다룰 때는 Number의 한계를 이해하고, 필요한 경우 BigInt를 적극 활용해야 합니다.
물론, 모든 경우에 BigInt가 최선은 아닙니다. 작은 정수 연산에서는 number 타입이 더 빠르고 효율적일 수 있습니다.
따라서 상황에 맞춰 적절한 숫자 타입을 선택하는 것이 중요합니다.
✅ 핵심 정리:
- Number.MAX_SAFE_INTEGER를 초과하는 정수는 정확도가 깨질 수 있음
- BigInt는 무제한 크기의 정수를 다룰 수 있지만 소수점 연산은 불가능
- 금융, 암호화, 블록체인, 팩토리얼 같은 문제에서는 BigInt가 필수
- Number와 BigInt는 혼합해서 사용할 수 없으며 명시적 변환이 필요
'Frontend > JavaScript' 카테고리의 다른 글
화살표 함수(Arrow Function) (0) | 2024.12.19 |
---|---|
JS 배열 구조 분해 할당(Destructuring Assignment) (0) | 2024.11.23 |
Javascript 비동기 프로그래밍, 클로저와 스코프, 모듈화, ES6 (0) | 2024.11.13 |
웹 브라우저의 동작 방식 (0) | 2024.11.11 |
HTTP와 HTTPS의 역사 (0) | 2024.11.10 |