求一个数的开*方,方法有很多,最简单的方法就是二分法,再上一个档次是牛顿迭代法,还有更上档次的算法涉及到更高深的数学知识。
这里只是尝试这两种方法。
1、二分法求*方根,直接上代码。
1 /************************************************************************* 2 **File Name :mysqrt.c 3 **Author : 4 **Contact : 5 **Created Time :Tue 13 May 2014 09:58:54 AM CST 6 **Brief : 7 **Development note : 8 ************************************************************************/ 9 #define E 0.001 10 #define ABS(a) (((a)>0)?(a):(-(a))) 11 /********************************include*********************************/ 12 #include<stdio.h> 13 double sqrtby2(int N) 14 { 15 if(N == 0) 16 return 0; 17 if(N < 0) 18 return -1; 19 double mid; 20 double start = 0; 21 double end = N; 22 mid = (start + end)/2.0; 23 while(ABS(mid*mid - N) > E){ 24 if(mid*mid > N) 25 end = mid; 26 else 27 start = mid; 28 mid = (start + end) / 2.0; 29 } 30 return mid; 31 }
---------------------编写代码中遇到的问题----------------------------
宏的使用,宏所做的是字符串和参数的替换,虽然知道这一点,但是没有较深的体会,编写ABS宏时,由于宏参数在定义中未使用括号,导致返回值错误。
2、牛顿迭代法
牛顿迭代法主要用来求方程的*似解,其最大有点事在方程的单根附**方收敛。一下参考自百度百科:
设r是的根,选取
作为r的初始*似值,过点
做曲线
的切线L,L的方程为
![](http://a.hiphotos.baidu.com/baike/s%3D180/sign=bb2a367e530fd9f9a4175161152cd42b/00e93901213fb80e2b3e78d534d12f2eb83894c0.jpg)
![](http://d.hiphotos.baidu.com/baike/s%3D113/sign=4759ab76e9f81a4c2232e8c8e42b6029/adaf2edda3cc7cd9c67a2ddb3b01213fb80e9158.jpg)
过点
![](http://g.hiphotos.baidu.com/baike/s%3D71/sign=43308263f1deb48fff69a3dff11f38a8/c995d143ad4bd113cd3aaf3058afa40f4bfb0538.jpg)
![](http://h.hiphotos.baidu.com/baike/s%3D59/sign=a638fa186259252da7171d0d359bf9a9/810a19d8bc3eb1354c3bafb9a41ea8d3fd1f4437.jpg)
![](http://c.hiphotos.baidu.com/baike/s%3D113/sign=265ea26696eef01f49141cc4d3ff99e0/71cf3bc79f3df8dc43d19493cf11728b461028c7.jpg)
![](http://g.hiphotos.baidu.com/baike/s%3D15/sign=4e7e68110bf79052eb1f433b0df3edbc/5d6034a85edf8db1a5c967660b23dd54574e74c8.jpg)
重复以上过程,得r的*似值序列,其中,
![](http://a.hiphotos.baidu.com/baike/s%3D129/sign=763132a7087b020808c93be35bd9f25f/6a63f6246b600c339f73c4ca184c510fd9f9a1ad.jpg)
![](http://g.hiphotos.baidu.com/baike/s%3D33/sign=670fbe609a22720e7fcee4f97acbeb58/5d6034a85edf8db1a5eb67660b23dd54574e74ee.jpg)
用牛顿迭代法解非线性方程,是把非线性方程线性化的一种*似方法。把
![](http://h.hiphotos.baidu.com/baike/s%3D32/sign=a646f8186259252da7171b06359bf9a2/bd3eb13533fa828bd9a187e1ff1f4134970a5a35.jpg)
![](http://g.hiphotos.baidu.com/baike/s%3D15/sign=802826810d2442a7aa0ef9a0d04342de/6a63f6246b600c33993dc2ca184c510fd9f9a16f.jpg)
![](http://d.hiphotos.baidu.com/baike/s%3D559/sign=b957953d49fbfbedd859367a41f1f78e/8601a18b87d6277f7dd7363a2a381f30e824fcef.jpg)
![](http://a.hiphotos.baidu.com/baike/s%3D181/sign=a24d511560d0f703e2b291d439fb5148/37d3d539b6003af312d9db62372ac65c1038b654.jpg)
![](http://d.hiphotos.baidu.com/baike/s%3D59/sign=5082ab3058afa40f38c6ced4aa6459d9/eaf81a4c510fd9f9f458496b272dd42a2834a460.jpg)
![](http://g.hiphotos.baidu.com/baike/s%3D71/sign=8134fa0f72cf3bc7ec00cfedd1006a1d/060828381f30e9245ea49a334e086e061d95f7b4.jpg)
![](http://d.hiphotos.baidu.com/baike/s%3D113/sign=4759ab76e9f81a4c2232e8c8e42b6029/adaf2edda3cc7cd9c67a2ddb3b01213fb80e9158.jpg)
![](http://a.hiphotos.baidu.com/baike/s%3D129/sign=763132a7087b020808c93be35bd9f25f/6a63f6246b600c339f73c4ca184c510fd9f9a1ad.jpg)
。
已经证明,如果是连续的,并且待求的零点是孤立的,那么在零点周围存在一个区域,只要初始值位于这个邻*区域内,那么牛顿法必定收敛。 并且,如果不为0, 那么牛顿法将具有*方收敛的性能. 粗略的说,这意味着每迭代一次,牛顿法结果的有效数字将增加一倍。
1 /************************************************************************* 2 **File Name :mysqrt.c 3 **Author : 4 **Contact : 5 **Created Time :Tue 13 May 2014 09:58:54 AM CST 6 **Brief : 7 **Development note : 8 ************************************************************************/ 9 #define E 0.001 10 #define ABS(a) (((a)>0)?(a):(-(a))) 11 /********************************include*********************************/ 12 #include<stdio.h> 13 double sqrtbynewton(int N) 14 { 15 if(N == 0) 16 return 0; 17 if(N < 0) 18 return -1; 19 double x0 = N/2.0; 20 double x1; 21 while(ABS(x0*x0 - N) > E){ 22 x1 = (x0 + N/x0)/2.0; 23 x0 = x1; 24 } 25 return x0; 26 }