1. 程式人生 > 實用技巧 >如何求平方根 - Algorithm 第四版 - 讀書筆記

如何求平方根 - Algorithm 第四版 - 讀書筆記

如何求平方根

假如以我們人腦的思考方式去思考求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