1. 程式人生 > >根號2的計算方法(Java實現)

根號2的計算方法(Java實現)

出處:http://www.fengchang.cc/post/129

讀《西方哲學史》古希臘早期數學與天文學一章,看到一個有趣的求解根號2的方法,之前未曾見過。

 

思路如下:構造一個數對序列,初始值為(1,1),

然後對該數對依照如下規則進行演化:

下一個數對中的第一個數為前一個數對中兩個數之和,記為A+B,第二個數為2*A+B(A代表前個數對的第一個數,B代表前個數對的第二個數)

 

那麼依照如上規則,構造的數對序列如下:

 

那麼依照如上規則,構造的數對序列如下:

(1,1)

(2,3)

(5,7)

(12,17)

(29,41)

(70,99)

(169,239)

...

 

可以證明,第二個除以第一個數(暫且記為B/A)越往後越接近根號2.

 

證明方式如下:數對序列中的第n個我們記為(An, Bn),則可以構造(An,Bn)同(An-1, Bn-1)的遞推關係,構造完畢後,會發現一個規律:

2An^2-Bn^2=-(2An-1^2-Bn-1^2)

也就是隻變符號不變絕對值,

如果我們計算序列中第一個的值,很容易得到1,所以以上表達式2An^2-Bn^2的值的變化規律就是1,-1,1,-1。。。

記為2An^2-Bn^2=+-1,兩邊同時除以An^2,得到2-(An/Bn)^2=(+-1)/An^2

右邊項在n趨向於無窮大時,極限為0,那麼左邊An/Bn的值必然就趨向於根號2,所以n越大,也就是越到序列的後面,算出來的An/Bn越接近根號2.

 

上程式碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

public class Sqrt2 {

    public static double sqrt2(int iter_cnt){

        

int a =1, b=1;

 

        for(int i=0;i<iter_cnt;i++){

            int olda = a;

            a = olda+b;

            b = 2*olda+b;

            System.out.printf("After %d iteration, a is: %d, b is %d", i, a, b);

            System.out.println("");

        }

        double result = b*1.0/a;

        return result;

    }

 

    public static void main(String[] args) {

        int iter_cnt = 20;

        double result = sqrt2(iter_cnt);

        System.out.println(result);

    }

}

 

執行結果:

After 0 iteration, a is: 2, b is 3

After 1 iteration, a is: 5, b is 7

After 2 iteration, a is: 12, b is 17

After 3 iteration, a is: 29, b is 41

After 4 iteration, a is: 70, b is 99

After 5 iteration, a is: 169, b is 239

After 6 iteration, a is: 408, b is 577

After 7 iteration, a is: 985, b is 1393

After 8 iteration, a is: 2378, b is 3363

After 9 iteration, a is: 5741, b is 8119

After 10 iteration, a is: 13860, b is 19601

After 11 iteration, a is: 33461, b is 47321

After 12 iteration, a is: 80782, b is 114243

After 13 iteration, a is: 195025, b is 275807

After 14 iteration, a is: 470832, b is 665857

After 15 iteration, a is: 1136689, b is 1607521

After 16 iteration, a is: 2744210, b is 3880899

After 17 iteration, a is: 6625109, b is 9369319

After 18 iteration, a is: 15994428, b is 22619537

After 19 iteration, a is: 38613965, b is 54608393

1.4142135623730947

 

可以看出,這個值非常接近根號2的真值了.

 

僅僅迭代了20次而已,數對的值增長得非常快,如果要考慮完整,需要考慮溢位的情況,我這裡只為證明思路,沒有考慮溢位

 

這個方法的巧妙之處在於把開根號的運算轉換成了純的加減乘除四則運算解決的問題,可以算是“運算”上的降維。