/**
* 實現一個函數, 完成 開根號 的操作, 方法簽名如下.
*
* double sqrt(int v, double t)
* <p>
* 要求:
*
* 不能調用系統庫函數, 諸如 Math.sqrt(v) 之類的; 假設計算出的結果為 r, 要求滿足如下條件, , 其中 是真實的值, t 為給定的一個誤差范圍, 例如0.1等, 即你計算出的值要在給定的誤差范圍內. 實現語言不限,
* 你條件可以比上述更加苛刻, 但不能寬松, 舉例而言, 我調用你的接口 sqrt(9, 0.21) 返回值屬于 [2.79, 3.21] 這個區間的任意一個都滿足條件.
* </p>
*
*/
public class SqrtDemo {
// 窮舉法
private static double sqrt1(int v, double t) {
double result = 0;
Long start = new Date().getTime();
while (true) {
if ((result + t) * (result + t) >= Math.abs(v - t)) {
Long end = new Date().getTime();
System.out.println("自寫爆菊耗時:" + (end - start) + "ms");
return result;
}
result += t;// 適當分段
}
}
// 二分法
private static double sqrt2(int v, double t) {
Long start = new Date().getTime();
double value = v / 2;
double low = 0, up = v;
while (Math.abs(up - value * value) > t) {
if (value * value > v) {
low = 0;
up = value;
} else if (value * value < v) {
low = value;
}
if (value == (low + up) / 2)
break;
value = (low + up) / 2;
}
Long end = new Date().getTime();
System.out.println("自寫二分耗時:" + (end - start) + "ms");
return value;
}
// !!牛頓快速迭代法
// 求出根號a的近似值:首先隨便猜一個近似值x,然后不斷令x等于x和a/x的平均數,迭代個六七次后x的值就已經相當精確了。
// 不斷用(x,f(x))的切線來逼近方程x^2-a=0的根。根號a實際上就是x^2-a=0的一個正實根,這個函數的導數是2x。
// 也就是說,函數上任一點(x,f(x))處的切線斜率是2x。那么,x-f(x)/(2x)就是一個比x更接近的近似值。
// 代入f(x)=x^2-a得到x-(x^2-a)/(2x),也就是(x+a/x)/2。
private static double sqrt3(int v, double t) {
double result = 0, value = v;
Long start = new Date().getTime();
while (true) {
result = value;
value = (value + v / value) / 2;
if (Math.abs(result - value) <= t) {
Long end = new Date().getTime();
System.out.println("自寫牛頓耗時:" + (end - start) + "ms");
break;
}
}
return result;
}
public static void main(String[] args) {
System.out.println(sqrt1(1000000000, 0.00001));
System.out.println(sqrt2(1000000000, 0.00000001));
System.out.println(sqrt3(1000000000, 0.00000001));
Long start = new Date().getTime();
Math.sqrt(10000000);
Long end = new Date().getTime();
System.out.println("系統sqrt耗時:" + (start - end) + "ms");
System.out.println(Math.sqrt(1000000000));
}
}
自寫爆菊耗時:5530ms
31622.776601556234
自寫二分耗時:0ms
31622.776601683792
自寫牛頓耗時:0ms
31622.776601684047
系統sqrt耗時:0ms
31622.776601683792
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。