자바스크립트에서 안전한 최대 정수 값은 얼마일까?
1분 읽기
자바스크립트에서 아래 두 수는 같을까요?
console.log(9007199254740992 === 9007199254740993); // ?직관적으로는 당연히 다른 수입니다. 그런데 자바스크립트에서 실행해보면 true가 반환됩니다.
자바스크립트는 정수를 253 - 1까지만 안전하게 표현할 수 있습니다. 이 범위를 넘으면 에러가 나지 않고, 조용히 틀린 값을 반환합니다. 바로 위처럼요.
왜 자바스크립트는 큰 정수를 제대로 표현하지 못할까요?링크를 제목에 복사
자바스크립트의 Number 자료형은 IEEE 754 배정밀도 부동소수점 형식을 사용합니다. 64비트로 실수를 표현하는데, 구조가 이렇습니다.
| 비트 | 역할 |
|---|---|
| 1비트 | 부호 |
| 11비트 | 지수부 |
| 52비트 | 소수부(가수부) |
정수도 이 구조를 벗어날 수 없습니다. 소수부 52비트에 암묵적인 1비트를 더한 53비트가 정수를 안전하게 표현할 수 있는 한계입니다.
결국 -(253 - 1)에서 253 - 1 사이를 벗어나는 정수는 더 이상 정확하게 표현할 수 없습니다.
자바스크립트에서 "안전한" 정수 범위를 어떻게 알 수 있을까요?링크를 제목에 복사
여기서 **"안전하다"**는 건 정수를 정확하게 표현하고 올바르게 비교할 수 있다는 뜻입니다.
Number.MAX_SAFE_INTEGER로 안전한 최댓값을 확인할 수 있습니다. 값은 253 - 1, 즉 9007199254740991입니다.
const x = Number.MAX_SAFE_INTEGER + 1;
const y = Number.MAX_SAFE_INTEGER + 2;
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.isSafeInteger(x)); // false
console.log(Number.isSafeInteger(y)); // false
console.log(x === y); // true ← 다른 값인데 같다고 나옵니다Number.isSafeInteger()로 특정 값이 안전한 범위 안에 있는지도 검사할 수 있습니다. 처음 예시로 돌아가면, id1과 id2가 같다고 나온 이유가 바로 이것입니다. 두 값 모두 Number.MAX_SAFE_INTEGER를 넘었기 때문에 같은 부동소수점 값으로 수렴한 것입니다.
253 - 1을 초과하는 정수는 어떻게 다뤄야 할까요?링크를 제목에 복사
그래서 자바스크립트는 BigInt를 제공합니다. BigInt는 Number와 달리 크기 제한 없이 정수를 안전하게 처리할 수 있습니다.
// 리터럴 뒤에 n을 붙입니다
const theBiggestInt = 9007199254740991n;
// BigInt() 함수로도 만들 수 있습니다
const alsoHuge = BigInt(9007199254740991); // 9007199254740991n단, BigInt를 다시 Number로 변환하면 정확도를 잃을 수 있습니다. 253을 초과하는 값을 다룬다면 처음부터 BigInt만 사용하는 것이 안전합니다.
정리하면링크를 제목에 복사
- 자바스크립트
Number는 IEEE 754 배정밀도 부동소수점 형식을 사용하기 때문에 표현 가능한 안전한 정수 범위가 존재합니다. - 안전한 최대 정수는
Number.MAX_SAFE_INTEGER(253 - 1 = 9007199254740991)이며,Number.isSafeInteger()로 검사할 수 있습니다. - 이 범위를 벗어나면 서로 다른 정수가 같은 값으로 취급되어 비교 연산이 의도대로 동작하지 않습니다.
- 큰 정수를 안전하게 다루려면
BigInt를 사용하고, 한 번BigInt를 쓰기 시작했다면Number로 다시 변환하지 않는 것이 좋습니다.
관련 글
자바스크립트로 구현하는 힙
힙(Heap) 자료구조의 개념과 Min Heap, Max Heap을 JavaScript와 TypeScript로 구현하는 방법을 정리합니다.
소수 구하기
소수 판별법과 소수를 구하는 알고리즘을 정리합니다.
[프로그래머스 Level 2] 미로 탈출
프로그래머스 미로 탈출을 BFS로 풀이합니다.
모든 글