JavaScript에서 Math.sqrt() 메서드를 사용하지 않고 숫자의 제곱근을 계산해야 하는 경우가 있습니다. 이 글에서는 양의 정수를 인수로 받아 해당 숫자의 제곱근을 찾아 반환하는 함수를 직접 구현하는 방법을 알아보겠습니다.
접근 방식: 뉴턴-랩슨 법
이 문제는 뉴턴-랩슨 법(Newton-Raphson method), 즉 소위 바빌로니아 법이라 불리는 수치 해석 기법을 활용하면 효율적으로 해결할 수 있습니다. 핵심 아이디어는 다음과 같습니다.
제곱근의 근삿값을 반복적으로 개선해 나가는 방식으로, 현재 추정값 res에 대해 다음 수식을 적용합니다.
res = res - ((res ** 2) - num) / (2 * res)
이 과정을 res²와 원래 숫자의 차이가 허용 오차(deviation)보다 작아질 때까지 반복하면, 원하는 정밀도의 제곱근을 얻을 수 있습니다.
구현 예제
다음은 위 로직을 구현한 코드입니다. 두 번째 매개변수로 정밀도(소수점 자릿수)를 지정할 수 있으며, 기본값은 0입니다.
const squareRoot = (num, precision = 0) => {
if (num <= 0) {
return 0;
};
let res = 1;
const deviation = 1 / (10 ** precision);
while (Math.abs(num - (res ** 2)) > deviation) {
res -= ((res ** 2) - num) / (2 * res);
};
return Math.round(res * (10 ** precision)) / (10 ** precision);
};
console.log(squareRoot(16));
console.log(squareRoot(161, 3));
console.log(squareRoot(1611, 4));코드 설명
- 입력 검증: 0 이하의 값이 들어오면 0을 반환합니다.
- 초기값 설정: 추정값
res를 1로 시작합니다. - 허용 오차 계산: 정밀도에 따라 오차 범위를 결정합니다. 예를 들어 정밀도가 3이면 오차는 0.001입니다.
- 반복 수렴: 오차 범위 내에 도달할 때까지 뉴턴-랩슨 공식으로 추정값을 갱신합니다.
- 결과 반올림: 지정된 정밀도만큼 소수점 자릿수를 맞춰 반환합니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
4 12.689 40.1373
16의 제곱근은 정확히 4이며, 161의 제곱근은 소수 셋째 자리까지 반올림한 12.689, 1611의 제곱근은 소수 넷째 자리까지 반올림한 40.1373으로 올바르게 계산된 것을 확인할 수 있습니다.
마무리
이처럼 Math.sqrt() 없이도 뉴턴-랩슨 반복법을 활용하면 원하는 정밀도의 제곱근을 손쉽게 계산할 수 있습니다. 이 알고리즘은 수렴 속도가 빠르기 때문에 큰 숫자에 대해서도 효율적으로 동작합니다.