1. 程式人生 > >java實現開根號的運算

java實現開根號的運算

面試的時候,偶然被問到,開根號的實現,雖然給面試官講解了思路,但是沒有實際實現過,今天閒來無事,就把自己的思路寫一下,做個筆記。

如果某個數字正好可以開根號為2個整數,例如1,4,9等,那就很簡單了。

如果某個數字不可以正好開根號為2個整數,而且要保留幾位精度,例如:2,3,5等,我們該怎麼辦呢?????

首先我們可以把這個數字分成整數部分和小數部分,分別計算。

例如√5≈2.236  我們可以先算出整數部分為2,然後在根據保留幾位精度,去計算小數部分。依次計算十分位、百分位和千分位等,然後把整數位+十分位+百分位+千分位+。。。,結果就是我們想要的結果了。

下面我寫了一個通用的方法,可以根據傳的引數來保留精度。

package comc.n;

import java.math.BigDecimal;

public class Square {

	public static void main(String[] args) {
		System.out.println(Math.sqrt(5));
		System.out.println(MathSqure(5, 6));
	}
	/**
	 * 
	 * @param n  需要開根號的資料
	 * @param m  需要保留的精度,即幾位小數
	 * @return
	 */
	public static double MathSqure(int n, int m){
		double[] arr = new double[m];
		if(m >0){
			arr = sc(m);
		}
		int s = sq(n);
		
		return sb(n, s, arr);
	}
	
	/**
	 * 計算整數位
	 * @param n
	 * @return
	 */
	public static int sq(int n){
		if( n == 1){
			return 1;
		}
		int tmp = 0;
		for(int i=1;i<=n/2+1;i++){
			if(i*i == n){
				tmp = i;
				break;
			}
			if(i*i > n){
				tmp = i-1;
				break;
			}
		}
		return tmp;
	}
	
	/**
	 * 計算要保留幾位小數
	 * @param m
	 * @return
	 */
	public static double[] sc(int m){
		double[] arr = new double[m];
		int num = 0;
		while(num != m){
			double f = 1;
			for(int i=0;i<=num;i++){
				f = f*10;
			}
			arr[num] = 1/f;
			num++;
		}
		return arr;
	}
	
	/**
	 * 開根號
	 * @param n
	 * @param j
	 * @param arr
	 * @return
	 */
	public static double sb(int n, double j, double[] arr){
		double tmp = j;
		for(int p=0;p<arr.length;p++){
			if(p>0){
				j = tmp;//計算過後的值(整數位+小數位的和,賦值給j,下面繼續運算)
			}
			for(int i=1;i<=9;i++){//小數位只有九位{0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9}
				tmp = i*arr[p]+j;//i*arr[p],相當於每次加0.1,0.2 ...
				if(tmp*tmp == n){
					return tmp;
				}
				if(tmp*tmp >n){
					//避免丟失精度
					BigDecimal c1 = new BigDecimal(Double.toString(tmp));
					BigDecimal c2 = new BigDecimal(Double.toString(arr[p]));
					tmp = c1.subtract(c2).doubleValue();
					break;
				}
			}
		}
		return tmp;
	}
}

輸出結果: