为什么我的代码在尝试打印正弦和余弦函数的结果时返回“nan”?

问题描述 投票:0回答:2

我正在尝试在终端上打印下一个结果,但是当我尝试将

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

一些帮助将不胜感激!预先感谢:)

c math printf
2个回答
4
投票

您的代码具有未定义的行为,因为

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;
}

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)

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.