스노우보드 참 좋아하는데 맨날 키보드 앞에만 있네

백준 10827 : a^b (실수 제곱값의 정확한 계산, BigDecimal) 본문

개발/Algorithm

백준 10827 : a^b (실수 제곱값의 정확한 계산, BigDecimal)

워너-비 2018. 4. 30. 18:37

백준 10827 : URL



시간 제한메모리 제한제출정답맞은 사람정답 비율
1 초256 MB129633329239.513%

문제

실수 a와 정수 b가 주어졌을 때, a의 b제곱을 정확하게 계산하는 프로그램을 작성하시오.

입력

첫째 줄에 a와 b가 주어진다. (0 < a < 100, 1 ≤ b ≤ 100) a는 최대 소수점 9자리이며, 소수가 0으로 끝나는 경우는 없다.

출력

첫째 줄에 a의 b제곱을 출력한다.

예제 입력 1 

3.141592 3

예제 출력 1 

31.006257328285746688

예제 입력 2 

0.1 10

예제 출력 2 

0.0000000001

예제 입력 3 

1.01 5

예제 출력 3 

1.0510100501

힌트

 




문제 분석


실수A를 정수B번 제곱한 연산(A^B)의 정확한 값을 출력하는 문제다.

JAVA에서 제곱값은 Math 클래스의 pow를 이용하는게 대부분이지만, Math.pow는 근사치를 수행하므로 정확한 값을 구할 수 없다.

실수의 제곱 연산 시 double타입의 정밀도가 최대 13자리이므로 소수표현범위를 초과하여 오차가 발생하기 때문이다.


따라서 java.math.BigDecimal 클래스를 이용해야한다.


BigDecimal클래스에서는 실수 123.456을 다음과 같이 표현한다.

1
2
3
private final BigInteger value;
private final int scale;
private transient int precision;



1
2
3
4
Big Decimal bd = new BigDecimal("123.456");
// value = 123456
// scale = 3
// precision = 6



이렇게 BigDecimal은 정수를 이용해서 실수를 표현하기 때문에 실수의 정확한 표현이 가능하다.


BigDecimal을 이용한 소스코드를 작성해보면 다음과 같다. (val^scale)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.Scanner;
import java.math.BigDecimal;
 
public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        
        // 실수 입력
        BigDecimal val = s.nextBigDecimal();
        // 정수 입력
        int scale = s.nextInt();
        
        // 제곱 연산 수행
        BigDecimal result = val.pow(scale);
        
        // 출력
        System.out.println(result);
    }
}



채점결과는 60%까지 잘가다가 오답발생..

0.1^10 의 값을 입력했을때, 1E-7 로 지수형태의 리터럴 값이 출력된다.

아마 이게 문제인듯


그렇다면, BigDecimal 객체의 toPlainString() 메서드를 이용하여 출력해보자.

toPlainString() 메서드는 BigDecimal의 지수필드가 없는 문자열 표현을 반환한.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.Scanner;
import java.math.BigDecimal;
 
public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        
        BigDecimal val = s.nextBigDecimal();
 
        int scale = s.nextInt();
        
        BigDecimal result = val.pow(scale);
        
        System.out.println(result.toPlainString());
    }
}
 



채점결과는 정답 !


혹시나 pow() 메서드가 문제인가 해서 다른 방법을 찾아보았는데,

BigDecimal 객체의 pow 메소드 대신 multiply() 메서드를 이용하여 직접 a를 b번 곱해주는 방법도 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.Scanner;
import java.math.BigDecimal;
 
public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        
        BigDecimal val = s.nextBigDecimal();
        int b = s.nextInt();
        
        BigDecimal result = BigDecimal.ONE;
        
        while(b-- > 0) {
            result = result.multiply(val);
        }
        
        System.out.println(result.toPlainString());
    }
}





Comments