본문 바로가기
Old Posts/Java

[Java] 오버플로우 없이 실수 다루기 - BigInteger 사용법 및 예제

by A6K 2021. 6. 23.

Java 혹은 C를 이용해서 프로그래밍하다보면 '오버플로우(Overflow)'라는 개념을 기억하고 있어야한다. 소수점을 가지고 있는 실수 타입의 데이터를 저장하기 위해서 double 혹은 float 타입의 변수를 선언하게 된다. 문제는 float 타입의 변수는 1.4E-45 ~ 3.4028235E38 사이의 값만 저장할 수 있다는 점이다. double 타입으로 선언하더라도 그 범위가 4.9E-324 ~ 1.7976931348623157E308 로 늘어날 뿐 모든 범위의 숫자를 정확하게 저장할 수 있는 것은 아니다.

게다가 부동 소수점 데이터의 경우 2진수로 데이터를 다루는 기본형 타입에서는 부정확한 결과가 나올 수도 있다. 따라서 정밀한 소수점 계산이 필요한 과학 데이터의 경우 double, float 타입을 바로 사용하지말고 다른 방법을 사용해야한다.

1. BigDecimal 

자바에서는 이런 부동소수점을 위한 타입의 저장 한계를 극복하기 위해서 BigDecimal 클래스를 제공하고 있다. BigDecimal 클래스는 정수를 문자열 형태로 저장하기 때문에 메모리가 부족하지 않은 이상 무한한 숫자를 저장할 수 있다.

2. BigDecimal 사용법

2.1 BigDecimal 선언

BigDecimal bigDecimal1 = new BigDecimal("1234.56787");
BigDecimal bigDecimal2 = BigDecimal.valueOf("1234.56787");

BigDecimal 클래스는 'java.math' 패키지에 선언되어 있다. BigDecimal 객체를 생성하기 위해 생성자에 만들려고하는 숫자를 문자열 형태로 넘겨주면 된다.

2.2 BigDecimal 연산

BigDecimal 클래스는 사칙연산과 나머지 연산을 메소드 형태로 제공하고 있다. 일반 float, double 변수처럼 '+', '-', '*', '/', '%' 연산을 사용하면 안된다.

BigDecimal bigDecimal1 = new BigDecimal("123");
BigDecimal bigDecimal2 = new BigDecimal("234");

// 더하기
System.out.println(bigDecimal1.add(bigDecimal2));
// 빼기
System.out.println(bigDecimal1.subtract(bigDecimal2));
// 곱하기
System.out.println(bigDecimal1.multiply(bigDecimal2));
// 나누기
System.out.println(bigDecimal1.divide(bigDecimal2));
// 나머지
System.out.println(bigDecimal1.remainder(bigDecimal2));

이 메소드들은 또 다른 BigDecimal 객체를 리턴한다.

2.3 BigDecimal 타입 변환

BigDecimal 클래스는 기본적으로 객체 형태로 다뤄진다. 따라서 특정 타입으로 타입 변환을 해야하는 경우가 있다.

BigDecimal bigDecimal = new BigDecimal("123");

int intNum = bigDecimal.intValue(); // int 타입으로 변환
long longNum = bigDecimal.longValue(); // long 타입으로 변환
float floatNum = bigDecimal.floatValue(); // float 타입으로 변환
double doubleNum = bigDecimal.doubleValue(); // double 타입으로 변환
String stringValue = bigDecimal.toString(); // 문자열 타입으로 변환

2.4 BigDecimal 비교

사칙 연산처럼 두 숫자의 비교 연산 역시 그대로 사용할 수 없고, 별도의 메소드를 통해서 사용해야한다.

BigDecimal bigDecimal1 = new BigDecimal("123.456");
BigDecimal bigDecimal2 = new BigDecimal("234.567");
		
// 같으면 0, 입력한 인자가 더 크면 -1, 입력한 인자가 더 작으면 +1
int compare = bigDecimal1.compareTo(bigDecimal2);
System.out.println(compare);

 

댓글