이제 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 같은 경우에 진짜 몰랐을때 고생이 많았는데 이제는 안그럴 것 같아 좋다.
이제 기본적인 알고리즘 이론들을 정리해볼까 한다.
몰랐을때도 풀긴했지만, 확실히 알아두고 가면 더 어려운 문제도 풀 수 있겠지.
댓글