개발은 재밌어야 한다
article thumbnail
반응형

일전에 백준에서 큰수에 대한 문제를 풀었을때 만났었던 클래스인데 이번에 또 만나게 되어 BigDecimal과 BigInteger에 대한 설명을 포스팅하려고 합니다.

 

 

BigInteger를 사용한 백준 문제 (10757번 큰 수 A+B)

https://www.acmicpc.net/problem/10757

 

10757번: 큰 수 A+B

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

www.acmicpc.net

 


 

MySQL에서 Data에 대한 매핑을 보다가 BIGINT 즉 큰수에 대한 값을 자바에서 convert해서 가져오는 과정에서 사용되는 클래스로 java.math.BigDecimal이 사용되는 것을 확인 할 수 있습니다.

 

그럼 BigDecimal과 BigInteger가 무엇인지에 대해서 알아보겠습니다.

 

BigDecimal 클래스

실수형 자료형으로 사용되는 float과 double등은 정밀도에 한계가 있어 원하는 값이 나오지 않을 수 있습니다.

왜냐하면 내부적으로 수를 저장할 때 이진수의 근사치를 저장하기 때문입니다. 저장된 근사치 값을 다시 십진수로 변환하면서 오차가 발생합니다.

 

반면에 BigDecimal 타입은 내부적으로 수를 십진수로 저장하여 아주 작은 수과 큰 수의 연산에 대해 거의 무한한 정밀도를 보장합니다.

그래서 속도가 느리고 사용하기 불편하지만, 숫자의 오차를 허용하지 않는 정확한 자료형이기 때문에 소수점 아래의 값조차 정확하게 계산해야 할 때 경우 해당 자료형을 사용하게 됩니다.

 

생성방법

// 문자열로 생성
BigDecimal bigDecimal = new BigDecimal("123.456");

//double 타입으로 생성-오차발생 가능성
BigDecimal bigDecimal = new BigDecimal(123.456);

//int, long 타입으로 생성
BigDecimal bigDecimal = new BigDecimal(123456);

//valueOf 생성
BigDecimal bigDecimal = BigDecimal.valueOf(123456);

BigDecimal은 기본적으로 생성자의 인자값에 문자열값을 넣어 생성이 가능한데,

double, int, long타입으로도 생성이 가능하다. double의 정밀도의 한계가 있어 사용하는 클래스 이므로 double타입으로 생성할 경우 오차 발생 가능성이 존재한다.

 

사칙연산

BigDecimal num1 = new BigDecimal("123.456");
BigDecimal num2 = new BigDecimal("789.123");

System.out.println("BigDecimal 덧셈 :" + num1.add(num2));
System.out.println("BigDecimal 뺄셈 :" + num1.subtract(num2));
System.out.println("BigDecimal 곱셈 :" + num1.multiply(num2));

// 나눗셈의 경우 무한대로 나눠질 수 있기에 자리 수를 정해준다.
// 아래의 경우는 소수점 아래 3자리까지만 출력했다.
// RoundingMode.HALF_EVEN은 Java의 기본 반올림 정책으로 금융권에서 사용하는 Bankers Rounding와 동일한 알고리즘
System.out.println("나눗셈 :" + num1.divide(num2, 3, RoundingMode.HALF_EVEN));

System.out.println("나머지 :" + num1.remainder(num2));
BigDecimal 덧셈 :912.579
BigDecimal 뺄셈 :-665.667
BigDecimal 곱셈 :97421.969088
BigDecimal 나눗셈 :0.156
BigDecimal 나머지 :123.456

BigDecimal은 기본적으로 +,-,*,/과 같은 사칙연산을 그대로 사용할 수 없어서 .add() .substract() .multiply() .divide()와 같이 메소드를 사용하여 사칙 연산을 할 수 있다.

나눗셈을 사용할때에는 소수점의 표시를 하는 것을 주의하자

 

BigDecimal 값 비교 

거의 이 포스팅을 하는 이유라고 보면 될 것 같다.

BigDecimal은 >,<와 같이 일반적으로 값을 비교한는 것이 불가능하다.

그래서 메소드를 통해서 값 비교를 하여 누가 더 큰지 작은지를 판별 할 수 있다.

BigDecimal num1 = new BigDecimal("123.567");
BigDecimal num2 = new BigDecimal("456.789");

// 같으면 0 반환, 적으면 -1, 많으면 1 반환
int result = num1.compareTo(num2);
System.out.println("결과 : " + result);
결과 : -1

 

compareTo() 메소드를 사용하여 값의 대소를 비교한다.

값을 넣는 기준으로

앞의 숫자가 크면 1, 같으면 0, 뒤의 숫자가 크면 -1 이렇게 생각해서 외우면 편할 것 같다.

 

BigDecimal 에서 다른  자료형으로 형 변환

BigDecimal num = new BigDecimal("123.456");
    
String String_num = num.toString(); // String형으로 변환
int int_num = num.intValue(); // int형으로 변환
float float_num = num.floatValue(); // float형으로 변환
double double_num = num.doubleValue(); // double형으로 변환 
long long_num = num.longValue(); // long형으로 변환

각각

BigDecimal을 String로 형변환

BigDecimal을 int로 형변환

BigDecimal을 float로 형변환

BigDecimal을 double로 형변환

BigDecimal을 long로 형변환

하는 방법이다.

 

 

 

 

 

BigIntger 클래스

long형으로도 표현이 안되는 엄청나게 큰 범위의 정수를 표현할때 사용하는 클래스이다. BigDecimal과 마찬가지로 

(+,-,*,/,%)을 기호로 사칙연산을 할 수 없고, BigInteger에서 제공하는 메서드를 이용해야 한다.

참고로 BigIntger의 범위는 무한대이므로 단순히 long을 벗어나는 범위를 넘어 엄청나게 큰 수의 표현에서 사용한다고 보면 될 것 같습니다.

 

 

생성방법

// 문자열로 생성
BigInteger bigInteger = new BigInteger("123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789");

//n진수 문자열로 생성
BigInteger bigInteger = new BigInteger("FFFF", 20);

//valueOf 생성
BigInteger bigInteger = BigInteger.valueOf(123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789);

long형의 범위는 -9223372036854775808~9223372036854775807까지를 표현을 할 수 있다.

대충 19자리 정도까지는 long형으로 표현이 가능하나 그것을 넘는 숫자부터는 long형으로 표현이 불가능해서 BigInteger클래스를 사용해야 한다.

 

사칙연산

BigInteger bigNum = new BigInteger("3");
// 덧셈
System.out.println("3+3="+bigNum.add(BigInteger.valueOf(3)));
// 뺄셈
System.out.println("3-3="+bigNum.subtract(BigInteger.valueOf(3)));
// 곱셈
System.out.println("3*3="+bigNum.multiply(BigInteger.valueOf(3)));
// 나눗셈
System.out.println("3/3="+bigNum.divide(BigInteger.valueOf(3)));
// 나머지
System.out.println("3%3="+bigNum.mod(BigInteger.valueOf(3)));
3+3=6
3-3=0
3*3=9
3/3=1
3%3=0

 

BigIntger값 비교 

BigDecimal과 마찬가지로 compareTo()를 사용하여 비교할 수 있다. 같으면 0, 앞 숫자가 더 크면 1, 뒷 숫자가 더 크면 -1을 반환한다.

System.out.println(BigInteger.valueOf(3).compareTo(BigInteger.valueOf(3)));//0
System.out.println(BigInteger.valueOf(3).compareTo(BigInteger.ONE));//1
System.out.println(BigInteger.ONE.compareTo(BigInteger.valueOf(3)));//-1

참고로 0,1,2,10은 BigInteger.ZERO, BigInteger.ONE, BigInteger.TWO, BigInteger.TEN으로 클래스에서 제공한다.

 

 

BigIntger 에서 다른  자료형으로 형 변환

BigInteger bigNumber = BigInteger.valueOf(12345); 
System.out.println(bigNumber.intValue()); // int형으로 변환
System.out.println(bigNumber.longValue()); // long형으로 변환
System.out.println(bigNumber.floatValue()); // float형으로 변환
System.out.println(bigNumber.doubleValue()); // double형으로 변환
System.out.println(bigNumber.toString()); // String형으로 변환

각각

BigInteger을 int로 형변환

BigInteger을 long로 형변환

BigInteger을 float로 형변환

BigInteger을 double로 형변환

BigInteger을 String로 형변환

하는 방법이다.

 

String을 BigIntger로 변환

String convertStringValue = "2022";
BigInteger convertBigIntgerValue = new BigInteger(convertStringValue);

 

 

 

 

 

 

그렇다면 위의 백준의 문제인

해당 문제도

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;

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 A = new BigInteger(st.nextToken());
        BigInteger B = new BigInteger(st.nextToken());
        System.out.println(A.add(B));
    }
}

위와 같이 사용할 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

참고

https://ajdahrdl.tistory.com/14

 

[JAVA] BigDecimal 자료형 사용방법

안녕하세요. 오늘은 정확도가 좋은 BigDecimal 자료형에 대해서 알아보겠습니다. 1. BigDecimal ? BigDecimal 자료형은 다른 자료형들. int, double, float들에 비해 사용하기 불편합니다. 그렇다면 이 자료형을

ajdahrdl.tistory.com

https://technote-mezza.tistory.com/104

 

[java] BigInteger,BigDecimal,long 큰 수의 표현-사용법

long 자료형 보통 정수는 기본 자료형인 int를 많이 사용한다. 하지만 int의 표현 범위를 넘는 값을 변수에 담아서 사용한다면 long형을 사용해야 한다. int long 저장공간 4byte 8byte 범위 -2147483648 ~ 21474

technote-mezza.tistory.com

 

 

반응형

'JAVA' 카테고리의 다른 글

[자바 Java] Java.sql.Time을 milliseond로 변환  (0) 2022.03.11
[자바 JAVA] 예외의 종류  (0) 2022.02.17
[JAVA 자바] 메소드 체이닝이란?  (1) 2022.01.11
profile

개발은 재밌어야 한다

@ghyeong

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!