본문 바로가기
Algorithm/Java

Java - BigInteger, BigDecimal

by ZaRi 2025. 9. 21.

이제 Big 이다. 이걸 몰라서, 알고리즘 문제를 틀린적이 많다. 

기존 숫자형을 통해서 수가 커질때 오버플로우를 안 일으키기 위해 아무리 숫자를 압축한다고 해도 사실 한개가 있다.

그것을 이걸로 해결할수 있다.

참고로 파이썬은 자동으로 된다고 알고 있다.....

 

 

BigInteger

먼저 BigInteger를 써야만 하는 이유를 확실히 알아야 합니다. 자바의 가장 큰 정수 자료형인 long은 8바이트로, 약 -922경 ~ +922경 (-2^63 ~ 2^63-1)까지 표현할 수 있습니다. 엄청나게 큰 숫자 같지만, 코딩 테스트의 특정 유형 앞에서는 무력해집니다.

 

 

생성 방법

생성 방법 설명 예시
new BigInteger("...") long 범위를 넘는 아주 큰 숫자를 담을 수 있는 유일한 방법입니다. BigInteger num1 = new BigInteger("12345...890");
BigInteger.valueOf(long) long 타입의 숫자를 BigInteger로 변환합니다. new보다 효율적입니다. BigInteger num2 = BigInteger.valueOf(100L);
미리 정의된 상수 ZERO, ONE, TEN은 자주 사용되므로 상수로 제공됩니다. BigInteger zero = BigInteger.ZERO;

 

 

사칙연산 

기능 메서드 설명 예시 (a = 10, b = 3)
덧셈 a.add(b) a + b a.add(b) → 13
뺄셈 a.subtract(b) a - b a.subtract(b) → 7
곱셈 a.multiply(b) a * b a.multiply(b) → 30
나눗셈 a.divide(b) a / b (몫) a.divide(b) → 3
나머지 a.remainder(b) a % b a.remainder(b) → 1

기존 연산자가 아닌 메서드를 사용해야 한다.

 

 

할당

BigInteger num1 = new BigInteger("100");
BigInteger num2 = new BigInteger("50");
num1.add(num2); // 덧셈 결과인 150은 허공으로 사라짐
// System.out.println(num1); // 여전히 100 출력```

// 올바른 사용법:
BigInteger num1 = new BigInteger("100");
BigInteger num2 = new BigInteger("50");
num1 = num1.add(num2); // 연산 결과를 다시 num1에 할당
// System.out.println(num1); // 150 출력

할당을 해주어야 한다. 안 그러면 적용이 안된다.

 

 

비교

a.compareTo(b) 의 결과는 int 타입이며, 그 의미는 다음과 같습니다.
1: a가 b보다 클 때
0: a와 b가 같을 때
-1: a가 b보다 작을 때

 

BigInteger a = new BigInteger("100");
BigInteger b = new BigInteger("200");

if (a.compareTo(b) < 0) { // a가 b보다 작은가? (-1 < 0 이므로 true)
    System.out.println("a is smaller");
}

 

 

형 변환

`BigInteger` 값을 `int`나 `long`으로 다시 바꿔야 할 때 사용합니다. 단, 변환하려는 타입의 범위를 넘어서면 데이터가 손실되므로 주의해야 합니다.

int i = big.intValue();
long l = big.longValue();
String s = big.toString();

 

 

예제 

백준 10757번 '큰 수 A+B' 문제를 BigInteger로 푸는 전형적인 코드입니다.

import java.io.*;
import java.math.BigInteger; // 잊지 말고 import!
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        // 입력받은 문자열을 그대로 BigInteger 생성자에 넘겨줍니다.
        BigInteger A = new BigInteger(st.nextToken());
        BigInteger B = new BigInteger(st.nextToken());

        // add 메서드를 사용하여 두 수를 더합니다.
        BigInteger result = A.add(B);
        
        System.out.println(result.toString());
    }
}

 

 

 

 

 

BigDecimal

BigDeciaml 은 말그대로 큰 정밀도의 소수를 다루기위한 클래스이다.

 

BigInteger: 무한한 크기의 **정수(Integer)**를 다루는 클래스. (e.g., 100!, 100 C 50)
BigDecimal: 무한한 정밀도의 **소수(Decimal)**를 다루는 클래스. (e.g., 금융 계산, 과학 계산)

 

거의 메소드는 같다. 다른 부분만 설명하겠다.

 

 

생성 방법

생성 방법 입력 타입 내부 동작 추천도 및 사용 상황
new BigDecimal(String) String 문자열을 그대로 사용하여 오차 없이 생성 ⭐⭐⭐⭐⭐ (최고)
가장 안전하고 명확한 방법. 항상 우선적으로 고려.
BigDecimal.valueOf(double) double double → String 변환 후 생성 ⭐⭐⭐⭐ (안전)
이미 double 타입 변수에 담긴 값을 변환해야 할 때 사용.
new BigDecimal(double) double double의 2진수 근사값을 그대로 사용 ⭐ (위험/사용금지)
의도치 않은 정밀도 오차를 유발하므로 절대 사용하지 말 것.

 

 

 

나눗셈 및 반올림 

기능 메서드 설명
나눗셈 a.divide(b, scale, mode) a를 b로 나누되, 소수점 scale 자리까지 구하고 mode 정책에 따라 반올림합니다.
반올림/자릿수 변경 num.setScale(scale, mode) num의 소수점을 scale 자리로 맞추고 mode 정책에 따라 반올림/처리합니다.

 

예시

// 나눗셈
BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("3");
BigDecimal result = a.divide(b, 5, RoundingMode.HALF_UP); // 10/3을 소수점 5자리까지 (반올림)
// result는 3.33333

// 반올림
BigDecimal num = new BigDecimal("1.235");
BigDecimal rounded = num.setScale(2, RoundingMode.HALF_UP); // 소수점 2자리까지 (반올림)
// rounded는 1.24

 

 

 

참고로 반올림 정책은 다음과 같다.

RoundingMode 설명 예시 (값: 1.235, 자릿수: 2)
HALF_UP 사사오입. 우리가 아는 일반적인 반올림입니다. 1.24
UP 올림. (0에서 멀어지는 방향) 1.24
DOWN 내림(버림). (0으로 가까워지는 방향) 1.23
CEILING Math.ceil과 동일. 양의 무한대 방향으로 올림. 1.24
FLOOR Math.floor과 동일. 음의 무한대 방향으로 내림. 1.23

 

 

 

 

기존 클래스와 비교

구분 기본 자료형 (long, double) 클래스 (BigInteger, BigDecimal)
메모리 크기 고정됨 (e.g., long = 8 bytes) 가변적 (숫자의 크기에 따라 변함)
범위 명확한 최솟값/최댓값 존재 이론상 무한 (메모리에 의해 제한됨)
저장 방식 값 자체를 비트로 직접 저장 숫자를 int 배열 등으로 쪼개서 저장하고 관리
성능 매우 빠름 (하드웨어에서 직접 연산) 상대적으로 느림 (메서드 호출 및 내부 로직 수행)

 

 

 

 

후기

드디어 일단 내가 생각한 자바 코딩테스트 준비를 위한 기본적인 것들을 정리했다.

Big 같은 경우에 진짜 몰랐을때 고생이 많았는데 이제는 안그럴 것 같아 좋다.

이제 기본적인 알고리즘 이론들을 정리해볼까 한다.

몰랐을때도 풀긴했지만, 확실히 알아두고 가면 더 어려운 문제도 풀 수 있겠지.

 

댓글