한국어

자바스크립트의 BigInt 타입에 대한 종합 가이드로, 기능, 사용법, 큰 정수 연산 처리에서의 활용 사례를 다룹니다. 자바스크립트의 한계를 극복하고 정밀하게 복잡한 계산을 수행하는 방법을 배워보세요.

JavaScript BigInt: 큰 정수 연산 마스터하기

자바스크립트는 다재다능한 언어이지만, 매우 큰 정수를 다룰 때 한계가 있습니다. 표준 `Number` 타입은 `Number.MAX_SAFE_INTEGER`로 알려진 특정 한계까지만 정수를 정확하게 표현할 수 있습니다. 이 한계를 넘어서면 계산이 부정확해져 예상치 못한 결과를 초래할 수 있습니다. 바로 이 지점에서 BigInt가 해결사로 등장합니다. ECMAScript 2020에 도입된 BigInt는 표준 `Number` 타입의 한계를 뛰어넘어 임의의 크기의 정수를 표현하고 조작할 수 있는 방법을 제공하는 내장 객체입니다.

BigInt의 필요성 이해하기

BigInt 이전에는 자바스크립트 개발자들이 큰 정수 계산을 처리하기 위해 라이브러리나 사용자 정의 구현에 의존해야 했습니다. 이러한 해결책들은 종종 성능 오버헤드와 복잡성 증가를 동반했습니다. BigInt의 도입은 큰 정수를 다룰 수 있는 네이티브하고 효율적인 방법을 제공하여 다음과 같은 다양한 분야에서의 활용 가능성을 열었습니다:

BigInt 값 생성하기

자바스크립트에서 BigInt 값을 만드는 주된 방법은 두 가지가 있습니다:

  1. `BigInt()` 생성자 사용: 이 생성자는 숫자, 문자열 또는 불리언 값을 BigInt로 변환할 수 있습니다.
  2. `n` 접미사 사용: 정수 리터럴에 `n`을 추가하여 BigInt를 생성합니다.

예제:

`BigInt()` 생성자 사용:


const bigIntFromNumber = BigInt(12345678901234567890);
const bigIntFromString = BigInt("98765432109876543210");
const bigIntFromBoolean = BigInt(true); // 결과는 1n
const bigIntFromFalseBoolean = BigInt(false); // 결과는 0n

console.log(bigIntFromNumber); // 출력: 12345678901234567890n
console.log(bigIntFromString); // 출력: 98765432109876543210n
console.log(bigIntFromBoolean); // 출력: 1n
console.log(bigIntFromFalseBoolean); // 출력: 0n

`n` 접미사 사용:


const bigIntLiteral = 12345678901234567890n;
console.log(bigIntLiteral); // 출력: 12345678901234567890n

중요 참고사항: 산술 연산에서 BigIntNumber 값을 직접 혼합하여 사용할 수 없습니다. 계산을 수행하기 전에 명시적으로 같은 타입으로 변환해야 합니다. 직접 혼합하려고 하면 `TypeError`가 발생합니다.

BigInt 산술 연산

BigInt는 다음을 포함한 대부분의 표준 산술 연산자를 지원합니다:

예제:


const a = 12345678901234567890n;
const b = 98765432109876543210n;

const sum = a + b;
const difference = a - b;
const product = a * b;
const quotient = a / 2n; // 참고: 나눗셈은 0을 향해 소수점 이하를 버립니다
const remainder = a % 7n;
const power = a ** 3n; // 거듭제곱은 예상대로 작동합니다

console.log("Sum:", sum); // 출력: Sum: 111111111011111111100n
console.log("Difference:", difference); // 출력: Difference: -86419753208641975320n
console.log("Product:", product); // 출력: Product: 1219326311370217957951669538098765432100n
console.log("Quotient:", quotient); // 출력: Quotient: 6172839450617283945n
console.log("Remainder:", remainder); // 출력: Remainder: 5n
console.log("Power:", power); // 출력: Power: 187641281029182300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n

중요 고려사항:

비교 연산자

표준 비교 연산자(`==`, `!=`, `<`, `>`, `<=`, `>=`)를 사용하여 BigInt 값을 다른 BigInt 값이나 심지어 Number 값과도 비교할 수 있습니다. 하지만, 타입 강제 변환의 가능성에 유의해야 합니다.

예제:


const a = 10n;
const b = 20n;
const c = 10;

console.log(a == b);   // 출력: false
console.log(a != b);   // 출력: true
console.log(a < b);    // 출력: true
console.log(a > b);    // 출력: false
console.log(a <= b);   // 출력: true
console.log(a >= b);   // 출력: false

console.log(a == c);   // 출력: true (타입 강제 변환)
console.log(a === c);  // 출력: false (타입 강제 변환 없음)

권장 사항: BigIntNumber 값을 비교할 때 예상치 못한 타입 강제 변환을 피하기 위해 엄격한 동등성(`===`)과 엄격한 부등성(`!==`)을 사용하세요.

BigInt와 Number 간 변환

BigIntNumber 간의 직접적인 산술 연산은 허용되지 않지만, 두 타입 간에 변환할 수는 있습니다. 그러나 BigInt 값이 `Number.MAX_SAFE_INTEGER`를 초과하는 경우 BigIntNumber로 변환할 때 정밀도 손실이 발생할 수 있다는 점에 유의해야 합니다.

예제:


const bigIntValue = 9007199254740991n; // Number.MAX_SAFE_INTEGER
const numberValue = Number(bigIntValue); // BigInt를 Number로 변환
console.log(numberValue); // 출력: 9007199254740991

const largerBigIntValue = 9007199254740992n; // Number.MAX_SAFE_INTEGER 초과
const largerNumberValue = Number(largerBigIntValue);
console.log(largerNumberValue); // 출력: 9007199254740992 (부정확할 수 있음)

const numberToBigInt = BigInt(12345); // Number를 BigInt로 변환
console.log(numberToBigInt); // 출력: 12345n

사용 사례 및 예제

암호학

암호화 알고리즘은 보안을 위해 종종 매우 큰 소수에 의존합니다. BigInt는 이러한 숫자들을 효율적으로 표현하고 조작하는 방법을 제공합니다.


// 예제: 간단한 (안전하지 않은) 키 쌍 생성
function generateKeyPair() {
  const p = 281n; // 소수
  const q = 283n; // 또 다른 소수
  const n = p * q; // 모듈러스
  const totient = (p - 1n) * (q - 1n); // 오일러의 토션트 함수

  // 1 < e < totient 이고 gcd(e, totient) = 1인 e(공개 지수)를 선택
  const e = 17n;

  // (d * e) % totient = 1이 되는 d(개인 지수)를 계산
  let d = 0n;
  for (let i = 1n; i < totient; i++) {
    if ((i * e) % totient === 1n) {
      d = i;
      break;
    }
  }

  return {
    publicKey: { n, e },
    privateKey: { n, d },
  };
}

const keyPair = generateKeyPair();
console.log("Public Key:", keyPair.publicKey);
console.log("Private Key:", keyPair.privateKey);

참고: 이것은 시연 목적으로만 사용된 단순화된 예제입니다. 실제 암호학에서는 훨씬 더 큰 소수와 더 정교한 알고리즘을 사용합니다.

금융 계산

특히 국제 거래에서 큰 금액을 다룰 때 정밀도는 매우 중요합니다. BigInt는 반올림 오류를 방지하고 정확한 계산을 보장할 수 있습니다.


// 예제: 복리 계산
function calculateCompoundInterest(principal, rate, time) {
  const principalBigInt = BigInt(principal * 100); // 센트로 변환
  const rateBigInt = BigInt(rate * 10000);       // 1만분의 1 퍼센트 단위로 변환
  const timeBigInt = BigInt(time);

  let amount = principalBigInt;
  for (let i = 0n; i < timeBigInt; i++) {
    amount = amount * (10000n + rateBigInt) / 10000n;
  }

  const amountInDollars = Number(amount) / 100;
  return amountInDollars;
}

const principal = 1000000; // 1,000,000달러
const rate = 0.05;    // 5% 이자율
const time = 10;     // 10년

const finalAmount = calculateCompoundInterest(principal, rate, time);
console.log("Final Amount:", finalAmount); // 출력: Final Amount: 1628894.6267774413 (대략)

이 예제에서는 계산 중 반올림 오류를 피하기 위해 원금과 이자율을 BigInt 값으로 변환합니다. 결과는 표시를 위해 다시 Number로 변환됩니다.

큰 ID 작업하기

분산 시스템에서는 여러 서버에 걸쳐 고유 ID를 생성하는 것이 어려울 수 있습니다. BigInt를 사용하면 충돌 가능성이 거의 없는 매우 큰 ID를 만들 수 있습니다.


// 예제: 타임스탬프와 서버 ID를 기반으로 고유 ID 생성
function generateUniqueId(serverId) {
  const timestamp = BigInt(Date.now());
  const serverIdBigInt = BigInt(serverId);
  const random = BigInt(Math.floor(Math.random() * 1000)); // 약간의 무작위성 추가

  // 값들을 결합하여 고유 ID 생성
  const uniqueId = (timestamp << 20n) + (serverIdBigInt << 10n) + random;
  return uniqueId.toString(); // 쉬운 처리를 위해 문자열로 반환
}

const serverId = 123; // 예제 서버 ID
const id1 = generateUniqueId(serverId);
const id2 = generateUniqueId(serverId);

console.log("Unique ID 1:", id1);
console.log("Unique ID 2:", id2);

BigInt와 JSON

BigInt 값은 기본적으로 JSON에서 지원되지 않습니다. BigInt를 포함하는 자바스크립트 객체를 `JSON.stringify()`를 사용하여 직렬화하려고 하면 `TypeError`가 발생합니다. JSON으로 작업할 때 BigInt 값을 처리하기 위한 몇 가지 옵션이 있습니다:

  1. 문자열로 변환: 직렬화하기 전에 BigInt를 문자열로 변환합니다. 이것이 가장 일반적이고 간단한 접근 방식입니다.
  2. 사용자 정의 직렬화/역직렬화: 사용자 정의 직렬화/역직렬화 함수를 사용하여 BigInt 값을 처리합니다.

예제:

문자열로 변환:


const data = {
  id: 12345678901234567890n,
  name: "Example Data",
};

// 직렬화 전에 BigInt를 문자열로 변환
data.id = data.id.toString();

const jsonData = JSON.stringify(data);
console.log(jsonData); // 출력: {"id":"12345678901234567890","name":"Example Data"}

// 역직렬화할 때, 문자열을 다시 BigInt로 변환해야 함
const parsedData = JSON.parse(jsonData, (key, value) => {
  if (key === "id") {
    return BigInt(value);
  }
  return value;
});

console.log(parsedData.id); // 출력: 12345678901234567890n

사용자 정의 직렬화/역직렬화 (`replacer`와 `reviver` 사용):


const data = {
  id: 12345678901234567890n,
  name: "Example Data",
};

// 사용자 정의 직렬화
const jsonData = JSON.stringify(data, (key, value) => {
  if (typeof value === 'bigint') {
    return value.toString();
  } else {
    return value;
  }
});

console.log(jsonData);

// 사용자 정의 역직렬화
const parsedData = JSON.parse(jsonData, (key, value) => {
    if (typeof value === 'string' && /^[0-9]+$/.test(value)) { // 문자열이면서 숫자인지 확인
      try {
        return BigInt(value);
      } catch(e) {
          return value;
      }
    }
    return value;
});

console.log(parsedData.id);

브라우저 호환성

BigInt는 최신 브라우저에서 널리 지원됩니다. 하지만 구형 브라우저나 환경에 대한 호환성을 확인하는 것이 중요합니다. Can I use와 같은 도구를 사용하여 브라우저 지원 여부를 확인할 수 있습니다. 구형 브라우저를 지원해야 하는 경우 폴리필(polyfill) 사용을 고려할 수 있지만, 폴리필이 성능에 영향을 줄 수 있다는 점을 인지해야 합니다.

성능 고려사항

BigInt는 큰 정수를 다루는 강력한 방법을 제공하지만, 잠재적인 성능 영향에 대해 인지하는 것이 중요합니다.

따라서, 필요할 때만 BigInt를 사용하고, 많은 수의 BigInt 연산을 수행하는 경우 성능을 위해 코드를 최적화하세요.

결론

BigInt는 자바스크립트에 추가된 귀중한 기능으로, 개발자들이 큰 정수 연산을 정밀하게 처리할 수 있게 해줍니다. 그 기능, 한계, 사용 사례를 이해함으로써, 암호학, 금융 계산, 과학 컴퓨팅 등 다양한 분야에서 견고하고 정확한 애플리케이션을 구축하는 데 BigInt를 활용할 수 있습니다. 프로젝트에서 BigInt를 사용할 때는 브라우저 호환성과 성능 영향을 고려하는 것을 잊지 마세요.

더 알아보기

이 가이드는 자바스크립트의 BigInt에 대한 포괄적인 개요를 제공합니다. 더 심도 있는 정보와 고급 기술에 대해서는 링크된 자료를 탐색해 보세요.