有什么方法可以不使用 math.h 和 sqrt() 来获取数字的平方根?
Any way to obtain square root of a number without using math.h and sqrt()?
我为 class 编写了一个程序,它使用 MPI 来执行 Fox 的块矩阵乘法方法。我能够通过使用 中的 sqrt() 函数来执行此操作,但为了编译程序,我必须输入 "mpicc -lm -o ..."。硬件状态说明使用 "mpicc -o ..." 编译程序,不带 -lm。我只是想知道是否有办法找到数字的平方根(无需编写单独的程序来这样做)。如果没有,我将把免责声明放在我的 .txt 文件顶部的注释中。认为这可能是一个问的好地方。谢谢!
为此您可以阅读babylonian-method。然后借助这个定理你可以找到sqrt()
我想。
计算 1/sqrt 有一个古老的计算机图形技巧:
(来自 Quake III 的原始代码)
float Q_rsqrt( float number ) {
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what is this?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
您可以阅读所有相关内容here
顺便说一句,我建议你只使用编译标志...
此方法使用逐次逼近法。它不需要很多迭代。因为root
的值可以抖动,我检查收敛到一个小误差。
//#define MINDIFF 2.2250738585072014e-308 // smallest positive double
#define MINDIFF 2.25e-308 // use for convergence check
double sqroot(double square)
{
double root=square/3, last, diff=1;
if (square <= 0) return 0;
do {
last = root;
root = (root + square / root) / 2;
diff = root - last;
} while (diff > MINDIFF || diff < -MINDIFF);
return root;
}
或者,您可以通过迭代固定次数来更简单地做到这一点
double sqroot(double square)
{
double root=square/3;
int i;
if (square <= 0) return 0;
for (i=0; i<32; i++)
root = (root + square / root) / 2;
return root;
}
这段代码给出的输出高达 0.000001,所以请检查一下。
该程序仅限于在 1 到 1050000000 之间查找。
{
int x;
printf ("Enter number : ");
scanf ("%d",&x);
int i=1,j=1;
float x0=1.0;
float xn=1.0;
for(i=1,j=1;i<x;i=i*10,j++)
if(x/i==0)
i=x;
i=i/10;
j=j-1;
if(j>1)
x0=j*power(10,j/2);
int a;
for(a=1;a<=10;a++)
{
xn=0.5*(x0+(x/x0));
x0=xn;
}
printf("\nSquare root of %d is %f",x,xn);
}
int power(int x,int n)
{
int pow=1;
int i;
for(i=1;i<n;i++)
pow=pow*x;
return pow;
}
下面是使用 Newton-Raphson 方法的平方根函数的实现。
基本思想是,如果 y
是对非负实数 x
的平方根的高估,那么 x/y
将是低估,反之亦然,因此,可以合理地期望这两个数字的平均值提供更好的近似值。
#define ABS(n) (((n) < 0) ? -(n) : (n)) /* Absolute function */
#define TOL 0.001 /* Tolerance */
float sqrt2(float x)
{
float y = 1.0;
while (ABS(x/y - y) > TOL )
{
y=(y+x/y)/2.0;
}
return y;
}
我为 class 编写了一个程序,它使用 MPI 来执行 Fox 的块矩阵乘法方法。我能够通过使用 中的 sqrt() 函数来执行此操作,但为了编译程序,我必须输入 "mpicc -lm -o ..."。硬件状态说明使用 "mpicc -o ..." 编译程序,不带 -lm。我只是想知道是否有办法找到数字的平方根(无需编写单独的程序来这样做)。如果没有,我将把免责声明放在我的 .txt 文件顶部的注释中。认为这可能是一个问的好地方。谢谢!
为此您可以阅读babylonian-method。然后借助这个定理你可以找到sqrt()
我想。
计算 1/sqrt 有一个古老的计算机图形技巧: (来自 Quake III 的原始代码)
float Q_rsqrt( float number ) {
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what is this?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
您可以阅读所有相关内容here
顺便说一句,我建议你只使用编译标志...
此方法使用逐次逼近法。它不需要很多迭代。因为root
的值可以抖动,我检查收敛到一个小误差。
//#define MINDIFF 2.2250738585072014e-308 // smallest positive double
#define MINDIFF 2.25e-308 // use for convergence check
double sqroot(double square)
{
double root=square/3, last, diff=1;
if (square <= 0) return 0;
do {
last = root;
root = (root + square / root) / 2;
diff = root - last;
} while (diff > MINDIFF || diff < -MINDIFF);
return root;
}
或者,您可以通过迭代固定次数来更简单地做到这一点
double sqroot(double square)
{
double root=square/3;
int i;
if (square <= 0) return 0;
for (i=0; i<32; i++)
root = (root + square / root) / 2;
return root;
}
这段代码给出的输出高达 0.000001,所以请检查一下。 该程序仅限于在 1 到 1050000000 之间查找。
{
int x;
printf ("Enter number : ");
scanf ("%d",&x);
int i=1,j=1;
float x0=1.0;
float xn=1.0;
for(i=1,j=1;i<x;i=i*10,j++)
if(x/i==0)
i=x;
i=i/10;
j=j-1;
if(j>1)
x0=j*power(10,j/2);
int a;
for(a=1;a<=10;a++)
{
xn=0.5*(x0+(x/x0));
x0=xn;
}
printf("\nSquare root of %d is %f",x,xn);
}
int power(int x,int n)
{
int pow=1;
int i;
for(i=1;i<n;i++)
pow=pow*x;
return pow;
}
下面是使用 Newton-Raphson 方法的平方根函数的实现。
基本思想是,如果 y
是对非负实数 x
的平方根的高估,那么 x/y
将是低估,反之亦然,因此,可以合理地期望这两个数字的平均值提供更好的近似值。
#define ABS(n) (((n) < 0) ? -(n) : (n)) /* Absolute function */
#define TOL 0.001 /* Tolerance */
float sqrt2(float x)
{
float y = 1.0;
while (ABS(x/y - y) > TOL )
{
y=(y+x/y)/2.0;
}
return y;
}