Integral Babylonian Method
바빌로니아 법
바빌로니아 법The Babylonian method은 임의의 수의 제곱근에 빠르게 수렴하는 수열을 통해 근사값을 얻는 방법이다. 임의의 양의 실수
- 임의의 양의 실수
를 택한다. 예컨대 와 같이 택할 수 있다. 에 대해, 을 계산한다. - 원하는 정밀도에 이르기까지 2의 과정을 반복한다.
위의 방법을 따라
이 글에서는 바빌로니아 법이 왜 양의 실수의 제곱근을 근사하는지 알아보고, 이를 problem-solving에서 활용하는 방법에 대해 소개한다.
바빌로니아 법 증명하기
양의 실수
임의의 실수
정수 바빌로니아 법
이 글의 제목인 “정수 바빌로니아 법”The integral Babylonian method은 임의로 지어낸 말로, problem-solving에서 간간히 필요로 하는 계산인 음이 아닌 정수의 제곱근의 바닥floor을 구하는 방법이다. 가급적이면 실수 계산을 피하고 싶어 만들게 되었는데, 이 절에서 정수 자료형과 바빌로니아 법을 사용하여 음이 아닌 정수의 제곱근의 바닥을 계산하는 C++ 함수와 그 정당성의 증명을 제시한다.
정수 바빌로니아 법의 C++ 구현
다음 integral_babylonian 함수는 정수형 입력
int integral_babylonian(int n) {
if (n < 0) return -1;
if (n == 0) return 0;
int p = n, x = (n + 1) / 2;
while (p > x) p = x, x = (x + n / x) / 2;
return p;
}
왜 이런 코드가 나왔는지 모르겠지만 어쨌든 잘 동작한다.
정당성과 시간 복잡도
위 알고리즘은
으로 정의되는 수열을 계산한다.
while 구문 내의 코드가 한 번 실행된 후 1을 반환한다. 이는 원하는 결과이다.
양의 정수
이다. 또한
위 계산이 고리를 만들게 된다. while문의 조건을 p > x와 같이 씀으로써
알고리즘 정당성에서 사용한 부등식
정수 바빌로니아 법의 효용
naïve한 선형 탐색은
이분 탐색을 사용해도
int sqrt_floor(int n) {
if (n < 0) return -1;
int l = 0, r = n + 1;
while (l + 1 < r) {
int m = (l + r) / 2;
if ((long long) m * m > N) l = m;
else r = m;
}
return l;
}
이 이분 탐색은 m * m을 계산할 때 오버플로우가 발생할 수 있음에 주의하자.
이분 탐색은 편리하고 범용성이 있지만, 제곱근 바닥을 계산하기 위해서 정수 바빌로니아 법을 사용하였을 때 다음과 같은 효용이 있을 것이다. 첫째로, 계산 식이 x = (x + n / x) / 2;와 같이 간단하기 때문에 구현을 암기하기 쉽다. 또한, m의 제곱을 계산할 때 발생할 수 있는 오버플로우 문제 또는 이분 탐색에서 흔히 범하는 탐색 범위를 설정하는데 발생할 수 있는 실수를 피할 수 있을 것이다. 그러나 여전히 while문의 조건을 헷갈릴 수 있다.