수를 입력받아, 해당 수의 제곱근 값을 Math.sqrt
없이 구하기
최대 소수점 둘째 짜리까지 구한 수를 문자열로 변환하여 출력한다. (소수점 셋째 자리에서 반올림)
public class Solution {
public static String computeSquareRoot(int num) {
double sqrtNum = 1;
double[] diffs = new double[]{1, 0.1, 0.01, 0.001};
for (int i = 0; i < diffs.length; i++) {
while (sqrtNum * sqrtNum < num) {
sqrtNum += diffs[i];
}
if (sqrtNum * sqrtNum == num) {
return String.format("%.2f", sqrtNum);
}
if (sqrtNum * sqrtNum > num) {
sqrtNum -= diffs[i];
}
}
return String.format("%.2f", sqrtNum);
}
public static void main(String[] args) {
String output = computeSquareRoot2(9);
System.out.println(output); // --> "3.00"
output = computeSquareRoot2(6);
System.out.println(output); // --> "2.45"
}
}
sqrtNum
이 num
에 근접할 때까지 각 자릿수마다 while문을 돌린다.num
이 클수록 시간이 오래 걸린다.해당 코드는 바빌로니아 법을 사용했다.
✅ 바빌로니아 법: 임의의 수의 제곱근에 빠르게 수렴하는 수열을 만들어 근삿값을 구하는 방법
바빌로니아 법은 n (실행하는 횟수)이 무한으로 갈수록, 임의의 수에 수렴한다.
하지만 n을 무한으로 보내면, 우리는 무한 루프를 돌게 되므로
하는 방법을 선택해야 한다.
💡 정밀도나 횟수를 어떻게 설정해야 할까?
아래의 코드는 정밀도(precision)를 0.0001
로 설정한 코드이다.
public class Solution {
public static String computeSquareRoot2(int num) {
double x = 1;
double compare = (double) num;
double precision = 0.0001;
while(!(compare-precision < x*x && x*x < compare + precision)){
if(x*x == num){
break;
}
x = (x + (num/x)) /2;
}
return String.format("%.2f", x);
}
public static void main(String[] args) {
String output = computeSquareRoot2(9);
System.out.println(output); // --> "3.00"
output = computeSquareRoot2(6);
System.out.println(output); // --> "2.45"
}
}
[참고]
https://bloodstrawberry.tistory.com/224?category=947704