我正在寻找不使用 sqrt 函数来求平方根的算法,然后尝试进行编程。我最终得到了 C++ 中的工作代码
#include <iostream>
using namespace std;
double SqrtNumber(double num)
{
double lower_bound=0;
double upper_bound=num;
double temp=0; /* ek edited this line */
int nCount = 50;
while(nCount != 0)
{
temp=(lower_bound+upper_bound)/2;
if(temp*temp==num)
{
return temp;
}
else if(temp*temp > num)
{
upper_bound = temp;
}
else
{
lower_bound = temp;
}
nCount--;
}
return temp;
}
int main()
{
double num;
cout<<"Enter the number\n";
cin>>num;
if(num < 0)
{
cout<<"Error: Negative number!";
return 0;
}
cout<<"Square roots are: +"<<sqrtnum(num) and <<" and -"<<sqrtnum(num);
return 0;
}
现在的问题是初始化声明中的迭代次数 nCount(这里是 50)。例如,要找出 36 的平方根,需要 22 次迭代,所以没有问题,而找到 15625 的平方根需要超过 50 次迭代,因此它将在 50 次迭代后返回 temp 的值。请为此给出解决方案。
有一个更好的算法,对于双数最多需要 6 次迭代才能收敛到最大精度:
#include <math.h>
double sqrt(double x) {
if (x <= 0)
return 0; // if negative number throw an exception?
int exp = 0;
x = frexp(x, &exp); // extract binary exponent from x
if (exp & 1) { // we want exponent to be even
exp--;
x *= 2;
}
double y = (1+x)/2; // first approximation
double z = 0;
while (y != z) { // yes, we CAN compare doubles here!
z = y;
y = (y + x/y) / 2;
}
return ldexp(y, exp/2); // multiply answer by 2^(exp/2)
}
算法从 1 开始,作为平方根值的第一个近似值。
然后,在每一步中,它通过在当前值之间取平均值来改进下一个近似值y
and x/y
. If y
= sqrt(x)
,将会是一样的。如果y
> sqrt(x)
, then x/y
< sqrt(x)
大约相同的数量。换句话说,它会收敛得非常快。
UPDATE:为了加快非常大或非常小的数字的收敛速度,已更改sqrt()
函数提取二进制指数并从数字中计算平方根[1, 4)
范围。现在需要frexp()
from <math.h>
获得二进制指数,但可以通过从 IEEE-754 数字格式中提取位来获得该指数,而不使用frexp()
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)