옛날에 한 왕자의 목숨을 구한 지혜로운 신하가 있었어요. 왕은 신하가 원하는 것이 무엇이든 주겠다고 약속했어요. 왕이 체스를 좋아한다는 것을 알고, 신하는 밀알을 갖고 싶다고 왕에게 말했어요. 체스판의 첫 번째 칸에는 한 알, 그다음 칸부터는 알의 수를 두 배씩 늘려서요.
체스판에 놓인 밀알의 개수를 계산해요.
체스판은 64개의 칸으로 이루어져 있어요. 1번 칸에는 밀알이 한 개, 2번 칸에는 두 개, 3번 칸에는 네 개가 놓이고, 그다음부터는 칸마다 두 배씩 늘어나요.
다음을 계산하는 코드를 작성해 봐요:
기본적으로 awk의 숫자는 배정밀도 부동소수점 수로 표현돼요. 이 방식은 53비트의 정밀도를 제공해요(매뉴얼의 표 16.3 참고). 아쉽게도 이 정도로는 이 연습 문제를 끝낼 수 없어요(스포일러: 한 테스트는 63비트의 정밀도를 요구해요).
"정밀도 부족"은 이렇게 나타나요:
$ gawk 'BEGIN {
n = 2 ^ 54
if (n == n + 1)
print "not enough precision"
else
print "OK"
}'
not enough precision
GNU awk는 관련 라이브러리가 awk 실행 파일에 함께 컴파일되어 있으면 임의 정밀도 수를 사용할 수 있어요. awk 버전을 확인하고 "GNU MPFR"이 있는지 찾아봐요:
$ gawk --version
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
...
있으면 -M 옵션으로 이 기능을 켜요:
$ gawk -M 'BEGIN {
n = 2 ^ 54
if (n == n + 1)
print "not enough precision"
else
print "OK"
}'
OK
내 awk에 -M이 없다면 어떻게 할까요? 그럴 때는 bc처럼 임의 정밀도 연산을 할 수 있는 외부 프로그램을 불러와야 해요. 이 방법의 예는 파이프에서 변수로 getline 사용하기 섹션을 참고해요.
더 읽을거리: 임의 정밀도 연산