这次我们来学习一下如何求平方根。在计算机中很难有精确的求出数据的平方根的算法,基本都是要求一个误差可接受范围内的近似值。治理我们取误差值为1e-5。
笔者的编程语言及环境如下
- 编程语言:c++
- 编译器:Code Blocks
- 系统: windows 10 x64
二分法
二分法求平方根的思路如下:
- 设置一个初始区间[0,n],若n<1则初始区间为[0,1]。
- 取区间中值mid的平方与数据n比较。
- 若数据n小则令区间变为[0,mid];否则变为[mid,n(或1)]。
- 若先后两次中值的差在误差范围内,则此次mid为平方根的近似值。
代码如下:
double sqrt(double number)//二分法
{
double low=0.0,high=number>1?number:1;
double mid=0,last=0;
do{
last=mid;
mid=(low+high)/2;
if(mid*mid>number)high=mid;
else low=mid;
}while(fabs(mid-last)>1e-5);
return mid;
}
以123456789012为测试数据结果如下

递归法(牛顿法)
迭代法求平方根的主要思路为:
- 令x为任意值(通常取数据n的一半)。
- 令y=(x+n/x)/2。
- 若x与y的差在误差范围内,则y为平方根近似值;否则令x=y执行第2步
代码如下:
double sqrt1(double number,double x)
{
double y=(x+number/x)/2;
return fabs(y-x)<0.001?y:sqrt1(number,y);
}
以123456789012测试结果如下:

卡马克法
可以在上文看到牛顿迭代算法的初值是任意的,一个好的初值可以大大降低迭代次数。卡马克算法所求的是平方根的倒数(在实际应用中平方根的倒数比平方根用的多)。卡马克算法可以理解为优化的迭代算法,其选择了一个极好的初值,将算法优化到一次或两次迭代就可以达到误差范围内。因为其涉及到浮点数在计算机内的存储方式及Magic Number,这里将不再赘述,有兴趣的可以自行百度。
因为其涉及到浮点数的存储,而系统中float与double的存储不一样,所以有float与double两种版本。
float版代码如下:
float sqrt(float x)
{
float xhalf = 0.5

本文介绍了三种求平方根的算法:二分法、牛顿法(递归法)和卡马克法。通过C++实现,以123456789012为例展示算法效果。卡马克算法以其高效的迭代次数和独特的实现方式脱颖而出,即使在float和double类型下也能快速达到高精度结果。

3万+

被折叠的 条评论
为什么被折叠?



