문제 해석
BigDecimal
BigDecimal은 JAVA에서 숫자를 정밀하게 표현할 수 있는 유일한 방법으로, 소숫점을 저장할 수 있는 가장 큰 타입인 double은 소수점의 정밀도에 대한 한계점이 있어 데이터가 유실될 수 있다.
-> 이를 보완하게 나온 것이 바로 BigDecimal이다
- precision : 숫자를 구성하는 전체 자리수이지만, 왼쪽 부터 0이 아닌 수로 시작하여 오른쪽부터 0이 아닌 수로 끝나는 위치까지의 총 자리수이다.
ex) 012345.67890라고 했을 때 11이 precision는 11이 아닌 9이다.
- scale : 전체 소수점 자리수이지만, 소수점 첫째자리부터 끝 소수점자리가 0이 아닌 것으로 끝날때까지의 자리수이다.
ex) 012345.67890라고 했을 때, scale은 5가 아니라 4이다.
//0
BigDecimal.ZERO
//1
BigDecimal.ONE
//10
BigDecimal.TEN
- double 타입으로 부터 BigDecimal 타입을 초기화하는 방법으로 가장 안전한 방법은 *문자열의 형태로 생성자에게 전달하는 것이다!
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
//0.000010000000000000000818030539140313095458623138256371021270751953125 값을 가짐
//하지만 우리가 기대한 값은 그대로의 값인 0.00001이다.
System.out.println("double을 사용한 경우 : " + new BigDecimal(0.00001));
//위의 문제를 해결하기 위해
System.out.println("String 사용한 경우 : " + new BigDecimal("0.00001"));
}
}
결과
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
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());
br.close();
//(0 < A,B < 10^10000) : 자료형 BigDecimal 을 사용
BigDecimal A = new BigDecimal(st.nextToken());
BigDecimal B = new BigDecimal(st.nextToken());
//BigDecimal는 숫자를 정밀하게 저장하표현할 수 있는 객체
//단점 : 느린 속도 & 복잡한 사용법
System.out.println(String.valueOf(A.add(B))); //A+B식으로 하지 못한다. add() 메서드를 사용해야함
}
}
결과
코드2(참고)
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());
StringBuilder sb = new StringBuilder();
br.close();
String A = st.nextToken();
String B = st.nextToken();
int flag = 0; //다음 자리수 증가하는지 마는지(올림 더하기)
//뒤부터 더해야 한다
for(int i = A.length()-1, j = B.length()-1; i >= 0 || j >= 0; i--, j--){
int num = flag;
if(i >= 0) num += A.charAt(i) - '0';
if(j >= 0) num += B.charAt(j) - '0';
if(num < 10){ //두 수를 더했을때 10보다 작으면 자리올림X
flag = 0;
}else{ //두 수를 더했을 때 10보다 크면 다음 자리수 올리고,해당 num에 10을 빼준다.
flag = 1;
num -= 10;
}
sb.append(num);
}
if(flag == 1){ //반복문이 끝났고 flag가 1인 경우는 마지막으로 자리 올림을 해줘야하는 것!
sb.append(1);
}
System.out.println(sb.reverse()); //계산을 일의자리수부터 했기 때문에 순서를 뒤집어야한다.
}
}
결과2
느낀점