如何求平方根 - Algorithm 第四版 - 讀書筆記
阿新 • • 發佈:2020-09-19
如何求平方根
假如以我們人腦的思考方式去思考求8的開方,由於我們知道2的平方為4,3的平方為9,所以我們可以用2.X去猜測,由於2.9的平方大於8,2.8的平方小於8,所以十分位確定了,然後我們再去按照同樣的方式去思考下一位。這樣一點點的去求得接近8的開方值的資料,直到我們達到需要的精度,比如保留三位小數就是2.828。
那如果以機器的角度去計算呢?答案當然也是猜,只是說以某個預設值去猜測然後逐步的接近目標值,然後也是達到需要的精度就停止。
那具體如何求解呢
有一個求解方法叫做牛頓-拉弗森方法,也叫做牛頓迭代法,這個方法基於一個很好理解的定理:切線是曲線的線性逼近,具體如下圖A。
圖A
如果我們將圖A的A處放大就可以得到下圖B:
圖B
可以看到圖B的A點處的切線與曲線十分的接近,而切線是直線,是線性的,所以可以說A點處的切線是f(x)的線性逼近,也就是在A點附近的切線應該是約等於f(x)的。
那麼利用這一點直覺
對於果求a值的開方,首先我們隨便找一個近似的x值(可以直接預設為a),如果我們不斷利用( x1,f(x1))位置的切線去逼近曲線 x^2 - a = 0 就可以去逐步接近真正的開方值,直到我們需要的精度。
那麼如何去逼近呢?
根號a是 x^2 = a 的一個正實根,而這個函式(x^2 = a )的導數為2x,所以說函式上的點(x1,f(x1))的切線斜率都為2,所以(x1,f(x1))處的切線方程為:f(x1)+ 2(x -x1)。 所以 x - f (x) /(2x)就是一個比x更接近答案的近似值,帶入f(x)=x^2 就可以得到新的近似值 = (x + a/x)/2。
程式碼實現
class SqureRoot { public static double sqrt(double c) { if (c < 0) return Double.NaN; double err = 1e-15; double t = c; while (Math.abs(t - c/t) > err * t) t = (c/t + t) / 2.0; return t; } public static void main(String[] args) {System.out.printf("Squre root of %f is %f",8.0,sqrt(8));
}
}
output:
Squre root of 8.000000 is 2.828427