我正在尝试在终端上打印下一个结果,但是当我尝试将
cos()
函数放入 asin()
中时,会发生一些情况。这是我的代码:
#include "stdio.h"
#include "math.h"
int main() {
float R7, R4, Roc2Y;
//Calculo de los angulos
Roc2Y = asin(-R7) * 180.0 / PI;
Roc2Z = asin(R4 / cos(Roc2Y)) * 180.0 / PI;
printf("\n"); //Linea en blanco
printf(" Resultado: \n");
printf(" Angulo r7 \n");
printf(" RY=%f\n", Roc2Y );
printf(" RZ=%f\n", Roc2Z ) ;
}
这就是它在终端上打印出来的内容:
Resultado:
Angulo r7
RY=11.506551
RZ=nan
一些帮助将不胜感激!预先感谢:)
您的代码具有未定义的行为,因为
R7
和 R4
均未初始化。计算结果没有意义,如果 asin
的参数碰巧有一个范围 [-1;1] 之外的值,则函数返回 NaN
,而不是值。
另请注意,标准标题
"stdio.h"
和 "math.h"
应写作 <stdio.h>
和 <math.h>
。
变量
Roc2Z
没有在发布的代码中的任何地方定义,PI
也没有定义,它不是C标准中定义的标识符。 M_PI
是在 POSIX 系统上定义的,但该宏并未由 C 标准指定,因此它可能在您的系统上不可用,特别是在严格遵循标准进行编译的情况下。
传递给
Roc2Y
的值 cos(Roc2Y)
的单位是度而不是弧度。最好以弧度进行所有计算,然后转换为角度仅用于显示。
这是修改后的版本:
#include <stdio.h>
#include <math.h>
#ifdef M_PI
// M_PI is defined on POSIX systems
#define PI M_PI
#else
#define PI 3.14159265358979323846264338327950288
#endif
int main() {
double R7 = 0.5, R4 = 0.5;
//Calculo de los angulos
double Roc2Y = asin(-R7);
double Roc2Z = asin(R4 / cos(Roc2Y));
printf("\n"); //Linea en blanco
printf(" Resultado: \n");
printf(" Angulo r7 \n");
printf(" RY=%f\n", Roc2Y * 180.0 / PI);
printf(" RZ=%f\n", Roc2Z * 180.0 / PI);
return 0;
}
谨慎使用
asin()
、acos()
。
@chqrlie 很好地识别了 OP 的大部分困境,但总的来说,问题仍然存在。
1.0之后的浮点数的反正弦是多少? (它的 NAN)。
x
和 asin(x)
中使用的导致 acos(x)
的许多计算都有一个小误差。 当误差达到 fabs(x) == nextafter(1, 2)
(|x|
略大于 1.0)时,这些三角函数将返回 NAN
。
还有其他选择。
请勿使用
asin(), acos()
。许多计算可以使用 atan2()
重写,这对小错误更宽容。
测试是否接近 1.0。
重构代码以从不形成数量级超过 1.0 的结果。 这通常非常具有挑战性(除了简单的剪辑测试之外)。
#define NEAR_ONE (1.0 + DBL_EPSILON*2) // Sample idea. Adjust to your needs)
if (fabs(x) > 1.0 && fabs(x) <= NEAR_ONE) {
x = copysign(1.0, x); // Magnitude of x, sign of y
}
y = acos(x);
OP的代码以
float
开头。
使用
double
,除非确实需要 float
。
当
float
是 double
时,请考虑使用 x
函数而不是 float
函数:float asinf(float)
、float acosf(float)
。