根号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次而已,数对的值增长得非常快,如果要考虑完整,需要考虑溢出的情况,我这里只为证明思路,没有考虑溢出

这个方法的巧妙之处在于把开根号的运算转换成了纯的加减乘除四则运算解决的问题,可以算是“运算”上的降维。

猜你喜欢

转载自blog.csdn.net/xunileida/article/details/84980588