실수 a와 정수 b가 주어졌을 때, a의 b제곱을 정확하게 계산하는 프로그램을 작성하는 문제이다.
수를 문자열로 입력받아 단순하게 float로 변환해 제곱 연산을 수행하면 이진수로 변환해 연산을 수행하는 컴파일러 구조 특성상 오차가 발생할 수 밖에 없다. 따라서 소수부가 없어질 때 까지 10을 곱해서 정수로 만들어 준 다음 제곱 연산을 수행해야 오차가 발생하지 않는다. 파이썬의 경우 동적으로 int의 범위가 정해지므로 여기서부터는 신경쓰지 않아도 되지만, 다른 언어(java, c++ 등)의 경우에는 수의 범위를 신경써줘야 할 것 같다.
정수로 변환하기 위해서 10을 곱해주는 과정을 대체하는 방법으로 소수점의 위치를 find 메서드를 통해 알아냈다.
e = (len(a) -1) - a.find('.') # 소수점 위치
이후 단순히 문자열에서 소수점을 제거하여 정수로 만들고 제곱 연산을 수행했다. 제곱 연산의 피연산자 b만큼 10을 몇 번 곱해줬는지를 의미하는 변수 e도 곱해주어야 한다. 이제 e에는 정수부의 제곱 연산 후 최종 소수점의 위치가 담겨 있다.
result = str(int(a) ** int(b)) # 정수 제곱 연산
e *= int(b) # 소숫점도 그만큼 연산
주의해야할 점은 0.1의 10제곱을 구해야하는 경우 같이 정수부의 수가 부족한 경우를 고려해주어야 한다. 제곱 연산 후 길이가 e보다 작다면 차이만큼 앞에 0을 더해주자.
if len(result) < e:
result = '0'*(e-len(result)) + result # 정수로 변환할 때 숫자가 부족한 경우
이제 최종 소수점의 위치에 소수점을 더해주어야 한다. 이 때 위에서 예외로 0을 채운 경우 맨 앞에 소수점이 위치하게 되므로 예외로 0을 더해주어야 한다.
result = result[:-e] + '.' + result[-e:] # 최종 소수점 삽입
print(result) if result[0] != '.' else print('0' + result) # 예외 처리
import sys
input = sys.stdin.readline
def main():
a, b = input().rstrip().split()
e = (len(a) -1) - a.find('.') # 소수점 위치
a = a.replace('.', '') # 소수점 제거
result = str(int(a) ** int(b)) # 정수 제곱 연산
e *= int(b) # 소숫점도 그만큼 연산
if len(result) < e:
result = '0'*(e-len(result)) + result # 정수로 변환할 때 숫자가 부족한 경우
result = result[:-e] + '.' + result[-e:] # 최종 소수점 삽입
print(result) if result[0] != '.' else print('0' + result) # 예외 처리
if __name__ == '__main__':
main()