Javascript

[Javascript] 아주 큰 정수를 표현하는 BigInt 데이터 타입의 기초

apost 2023. 1. 23. 02:26

자바스크립트의 단점 중 하나인 아주 큰 정수 값을 표현할 수 없는 한계점을 해결해 주는 새로운 숫자 타입입니다.

Number와 구분되는 프리미티브 숫자 타입으로, 그동안 자바스크립트에서는 표현할 수 없었던 아주 큰 숫자를 표시하고, 연산할 수 있습니다.

 

Number 타입과 구분하기 위해 숫자 끝에 "n"을 붙여서 BigInt 숫자임을 표시해서 구분합니다.

나머지 사용법은 Number와 거의 유사합니다.

 

const bigInt = 127n;
const bigIntN = 9007199254740991n;

 

프리미티브 타입이므로 BigInt 숫자의 데이터 타입은 "bigint"로 표시됩니다.

 

console.log(typeof 1n)

 

 

BigInt 선언

 

BigInt 숫자는 아주 큰 정수 숫자 표현을 위해 자바스크립트에서 새롭게 제공되는 프리미티브 숫자 타입입니다.

먼저 기존 Number 숫자 타입으로 표현할 수 있는 최대 정수값부터 알아야 합니다.

자바스크립트에서 표현할 수 있는 Number 숫자의 최대 정수 표현 값은 다음처럼 상수로 정의되어 있습니다.

 

Number.MAX_SAFE_INTEGER //9007199254740993

 

BigInt는 이 숫자보다 큰 정수 숫자가 필요할 때 사용하면 됩니다. 

다만, 굳이 BigInt 객체가 아니어도 표현할 수 있는 정수 숫자를 BigInt로 정의해서 사용할 필요는 없습니다. 숫자 끝에 n을 붙여서 BigInt 타입임을 따로 구분해서 사용해야 하고, 몇 가지 제약 사항과 함께 번거로운 사용법이 있기 때문입니다.

제약 사항에 대해서는 뒤에서 다시 설명합니다.

 

BigInt 객체는 2가지 방법으로 생성할 수 있습니다. 

둘은 표현만 다르고 실제로 생성되는 것은 BigInt 타입으로 완전히 같습니다.

 

const bigIntN = 9007199254740991n //숫자 끝에 n을 붙여 선언
const bigIntNew = BigInt(9007199254740991) // 생성자로 선언

 

생성자로 선언할 때는 문자열이나 16진수로 선언할 수도 있습니다.

 

const bigIntString = BigInt("9007199254740991")
const bigIntHex = BigInt("0x1fffffffffffff")

 

 

 

 

BigInt 사칙연산

BigInt 정수 숫자에 사용할 수 있는 숫자 연산자는 사칙연산(+, -, *, /)과 제곱(**)입니다.

!중요한 주의사항이 있습니다.

BigInt 타입과 다른 숫자 타입, 즉 Number 타입과 혼합해서 연산을 하면 에러가 발생합니다. BigInt 타입과 Number 타입을 혼합해서 연산할 때는 Number 타입을 BigInt 타입으로 반드시 캐스팅해서 연산해야 합니다.

 

const bigIntPlus = 127 + 3n;

 

 

앞의 더하기 계산은 다음과 같이 명시적으로 BigInt로 숫자 타입 변환을 해야 합니다.

 

const bigIntPlus = 127n + 3n;
const bigIntPlus = BigInt(127) + 3n;

 

사칙 연산은 다음과 같이 합니다.

 

BigInt(Number.MAX_SAFE_INTEGER) + 1n//9007199254740992n
BigInt(Number.MAX_SAFE_INTEGER) - 100n//9007199254740891n
BigInt(Number.MAX_SAFE_INTEGER) * 2n//18014398509481982n
BigInt(Number.MAX_SAFE_INTEGER) / 8//1125899906842623n

 

!중요한 제약 사항이 있습니다.

사칙 연산 중 나누기를 할 때 발생하는 소수점은 BigInt 타입에서는 모두 버림 처리됩니다.

Number 타입에서는 5/2를 하면 2.5가 되지만, BigInt 타입은 정수값 타입이기 때문에 소수 부분은 모두 사라지게 됩니다.

 

console.log(5n / 2n) //2n

 

 

 

 

BigInt의 논리 연산과 불리언

 

불리언과 논리 연산자 연산은 Number 타입과 동일합니다.

 

  Boolean(0n) // false
  Boolean(1n) // true
  0n || 1n // 1n
  0n && 1n // 0n
  0n && 1n ? true:false //false
  0n || 1n ? true:false //true

 

 

 

 

혼합 BigInt 숫자 배열의 정렬

 

배열의 정렬도 BigInt 정수 타입의 제약 사항 중 하나입니다. Number 타입과 BigInt 타입이 혼합된 배열인 경우 기본 정렬 메서드로는 정상적인 정렬이 되지 않습니다.

Number와는 구분되는 완전히 다른 데이터 타입이므로 정렬할 때는 커스텀 정렬 함수를 인자로 넘겨서 다른 데이터 타입의 값을 비교할 수 있도록 별도의 정렬 처리를 해야 합니다.

 

먼저 다음 혼합 배열을 기본 정렬 메서드로 정렬해 보면 정상적으로 정렬이 되지 않습니다.

 

const mixed = [5n, 7, -100n, 15, 3n, 0, 25, 0n, 33, 27n]
mixed.sort() //[-100n, 0, 0n, 15, 25, 27n, 3n, 33, 5n, 7]

 

다음처럼 커스텀 정렬 함수를 인자로 넘겨서 비교할 수 있는 값(-1이나 1)으로 대소를 구분할 수 있도록 처리를 해야 합니다.

 

mixed.sort((a, b) => a > b?1:-1) //[-100n, 0n, 0, 3n, 5n, 7, 15, 25, 27n, 33]

 

정렬은 가능하지만, 그보다는 BigInt와 Number 가 혼합된 배열은 가능하면 사용하지 않는 것이 좋습니다.