Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C算法中的平方根问题_C_Algorithm_Sqrt_Ieee - Fatal编程技术网

C算法中的平方根问题

C算法中的平方根问题,c,algorithm,sqrt,ieee,C,Algorithm,Sqrt,Ieee,我有一段代码,可以在单位球面上找到一个点。回想一下,对于单位球体: 1=sqrt(x^2+y^2+z^2) 该算法在0和1之间选择两个随机点(x和y坐标)。如果它们的大小小于一,我们就有空间通过求解上面的z方程来定义第三个坐标 void pointOnSphere(double *point){ double x, y; do { x = 2*randf() - 1; y = 2*randf() - 1; } while (x*x + y*y > 1); double

我有一段代码,可以在单位球面上找到一个点。回想一下,对于单位球体:

1=sqrt(x^2+y^2+z^2)


该算法在0和1之间选择两个随机点(x和y坐标)。如果它们的大小小于一,我们就有空间通过求解上面的z方程来定义第三个坐标

void pointOnSphere(double *point){
double x, y;

do {
    x = 2*randf() - 1;
    y = 2*randf() - 1;
} while (x*x + y*y > 1);

double mag = sqrt(fabs(1 - x*x - y*y));

point[0] = 2*(x*mag);
point[1] = 2*(y*mag);
point[2] = 1 - 2*(mag*mag);
}
从技术上讲,我继承了这段代码。以前的所有者使用“无视严格的标准遵从性”的Ofast进行编译。TL;这意味着您的代码不需要遵循严格的IEEE标准。因此,当我试图在没有优化的情况下编译时,我遇到了一个错误

 undefined reference to `sqrt'
什么是IEEE标准?嗯,因为计算机无法将浮点数存储到无限精度,如果不小心,在某些计算过程中会出现舍入错误

在一些谷歌搜索之后,我遇到了一个让我在使用正确的IEEE材料方面走上正轨的问题。我甚至读过关于浮点数的书(我推荐)。不幸的是,它没有回答我的问题

我希望在函数中使用sqrt(),而不是类似的东西。我理解我的算法中的问题可能来自这样一个事实:我可能(尽管不是真的)将一个负数传递给sqrt()函数。我只是不太确定如何解决这个问题。谢谢你的帮助

如果相关的话,我用的是数字发生器


为了澄清,我将libm与-lm链接起来!我还确认它指向了正确的库。

至于对
sqrt
的未定义引用,您需要链接到
libm
,通常使用
-lm
或类似选项

还要注意

如果它们的大小小于一,我们就有空间通过求解上面的z方程来定义第三个坐标

void pointOnSphere(double *point){
double x, y;

do {
    x = 2*randf() - 1;
    y = 2*randf() - 1;
} while (x*x + y*y > 1);

double mag = sqrt(fabs(1 - x*x - y*y));

point[0] = 2*(x*mag);
point[1] = 2*(y*mag);
point[2] = 1 - 2*(mag*mag);
}

这是错误的。x和y必须满足x*x+y*y为确保点满足条件,测试条件本身,作为
循环的一部分,而不是条件的派生

// functions like `sqrt(), hypot()` benefit with declaration before use
//   and without it may generate "undefined reference to `sqrt'"
// Some functions like `sqrt()` are understood and optimized out by a smart compiler.
// Still, best to always declare them.
#include <math.h>

void pointOnSphere(double *point){
  double x, y, z;
  do {
    x = 2*randf() - 1;
    y = 2*randf() - 1;
    double zz = 1.0 - hypot(x,y); 
    if (zz < 0.) continue;  // On rare negative values due to imprecision
    z = sqrt(zz);
    if (rand()%2) z = -z;  // Flip z half the time
  } while (x*x + y*y + z*z > 1);  // Must meet this condition

  point[0] = x;
  point[1] = y;
  point[2] = z;
}
//像`sqrt()、hypot()`这样的函数在使用前通过声明受益
//如果没有它,可能会生成“对`sqrt'的未定义引用”
//智能编译器可以理解并优化某些函数,如'sqrt()'。
//不过,最好还是经常申报。
#包括
空心点球体(双*点){
双x,y,z;
做{
x=2*randf()-1;
y=2*randf()-1;
双zz=1.0-低气压(x,y);
if(zz<0.)continue;//由于不精确而导致的罕见负值
z=sqrt(zz);
如果(rand()%2)z=-z;//将z翻转一半时间
}while(x*x+y*y+z*z>1);//必须满足此条件
点[0]=x;
点[1]=y;
点[2]=z;
}
我会用


-Ofast
可能内联了
sqrt
调用。使用
-lm编译(特别是链接),你应该从你链接的问题中受益,这没有帮助吗?确保代码首先使用
#include
“算法选择0和1之间的两个随机点(x和y坐标)。
x=2*randf()-1不一致
x
[-10]
之间也可以有负值。您可能认为您正在链接libm,但它很清楚地告诉您您没有。听你的编译器。有时有一个问题是,
-lm
必须在
gcc
命令中排在最后。另外,可能编译器和/或库没有正确安装?这里所有的其他东西都是分心。找到图书馆!“x和y必须满足x*x+y*y@chux,也许吧。我会说,代码与文本不一致。或者文本非常模糊。我在解决问题的过程中很早就勾选了这个框。我已经链接了libm。这不是问题所在。你对数学的理解是正确的。然后你过早地勾选了这个框。其他一切都是错误的。”分散注意力——让编译器命令指向正确的库。是我自己还是这是唯一一个真正试图回答这个问题的答案?注意:使用球坐标确实会在球体上生成不同于OPs原始方法的点分布:可能更好,也可能更差。但最终计算的
|x,y,z|仍然可能超过1.0一点点。如果这是OP的一个问题,一个在过大幅度上重新生成的循环将很容易解决这个问题。