will come true

[백준] 10757번 - 큰 수 A+B (Java) 본문

Algorithm

[백준] 10757번 - 큰 수 A+B (Java)

haehyun 2022. 2. 9. 00:31

문제 

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

 

10757번: 큰 수 A+B

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

www.acmicpc.net

 

코드 (실패)

단위가 큰 정수를 입력으로 받는 문제이기에 단순히 long 타입으로 처리한 결과, 실제 입력값과 변수 타입이 매칭되지 않아 두 경우 모두 예외가 발생했다.

A. BufferedReader 로 입력받아서 long 타입으로 파싱 => NumberFormatException 예외 발생

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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(), " ");
        long a = Long.parseLong(st.nextToken());
        long b = Long.parseLong(st.nextToken());
        
        System.out.println(a + b);
    }
}

 

B. Scanner로 long 타입으로 입력 받기 => InputMismatchException 예외 발생

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long a = sc.nextLong();
        long b = sc.nextLong();

        System.out.println(a + b);
    }
}

 

코드 (성공)

long 보다 큰 범위 값을 처리하는 BigInteger 타입 객체로 값을 받아 처리하였다. BigInteger 클래스 생성자에 String 타입 문자열을 전달해 객체를 생성한다. 객체이니 만큼 BitInteger 타입 변수 a, b를 a+b하는 덧셈 산술 연산자(+)는 사용하지 못 하고 a.add(b) 와 같이 객체의 메서드를 사용해야 한다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
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 a = new BigInteger(st.nextToken());
        BigInteger b = new BigInteger(st.nextToken());

        System.out.println(a.add(b));
    }
}

 

java.math.BigInteger 클래스

public class BigInteger extends Number implements Comparable<BitInteger> {
    final int signum;	// 부호. 1(양수), 0, -1(음수)
    final int[] mag;	// 값(magnitude)
}
  • 가장 큰 정수형 타입인 long으로 표현할 수 있는 값(10진수로 19자리 정도) 보다 큰 값을 다뤄야 할 때 사용한다.
  • 내부적으로 int배열을 사용해서 값을 다룬다.
  • 자릿수가 큰 정수의 각 자릿 값을 하나씩 배열 요소로 가지고 있는 구조.

 

  • 일반적으로 생성자에 정수 문자열을 넘겨 생성한다.
BigInteger val;
val = new BigInteger("12345678901234567890");	// 문자열로 생성
val = new BigInteger("FFFF", 16);				// n진수(radix)의 문자열로 생성
val = BigInteger.valueOf(1234567890L);			// 숫자로 생성

 

  • BigInteger를 String, byte배열, Number로 부터 상속받는 기본형 등으로 변환할 수 있다.
  • '~Exact' 로 끝나는 메서드들은 변환 결과가 타입의 범위에 속하지 않으면 ArithmeticException을 발생시킨다.
String toString()            // 문자열
String toString(int radix)   // 지정된 진법(radix)의 문자열
byte[] toByteArray()         // byte 배열

int intValue()
long longValue()
float floatValue()
double doubleValue()

byte byteValueExact()
int intValueExact()
long longValueExact()

 

  • BigInteger 타입의 연산은 객체에 정의된 메서드를 이용한다.
  • 큰 숫자를 다루는 타입이기 때문에 성능 향상을 위해 비트단위로 연산을 수행하는 메서드들을 가지고 있다.
BigInteger add(BigInteger val)         // 덧셈
BigInteger substract(BigInteger val)   // 뺄셈
BigInteger multiply(BigInteger val)    // 곱셈
BigInteger divide(BigInteger val)      // 나눗셈
BigInteger remainder(BigInteger val)   // 나머지

int        bitCount()      // 2진수로 표현했을 때, 1의 개수(음수는 0의 개수)를 반환
int        bitLength()     // 2진수로 표현했을 때, 값을 표현하는데 필요한 bit수
boolean    testBit(int n)  // 우측에서 n+1번째 비트가 1이면 true, 0이면 false
BigInteger setBit(int n)   // 우측에서 n+1번째 비트를 1로 변경
BigInteger clearBit(int n) // 우측에서 n+1번째 비트를 0으로 변경
BigInteger flipBit(int n)  // 우측에서 n+1번째 비트를 전환 (1이면 0, 0이면 1)

 

+) java.math.BigDecimal 클래스

  • 실수 쪽에도 BigInteger과 유사한 클래스로 BigDecimal 클래스가 존재한다.
  • double 타입의 정밀도 한계와 오차 문제를 극복하기 위해 사용하는 클래스
  • 실수를 정수와 10의 제곱의 곱으로 표현한다. (=10진 실수를 오차가 없는 2진 정수로 변환하여 다루는 것)

 


참고자료

  • Java의 정석 3판 - Chapter 09 java.lang패키지와 유용한 클래스, 518p
Comments