首页 > 解决方案 > 使用浮点数时计算错误

问题描述

我正在尝试进行计算,由于某种原因,当我使用 float 时,我得到 -nan(ind) 但是当我将变量 (x,y) 更改为 double 时,我可能会得到正确的答案你们知道为什么会这样吗?谢谢

#include <stdio.h>
#include <math.h>

#define pi 3.1416
#define L1 0.5
#define L2 0.5

void main()
{
    float q1[12], q2[12], q1_Degrees[12], q2_Degrees[12];
    float x = 0.8;
    float y = 0.6;

    q2[0] = acos((pow(x, 2) + pow(y, 2) - pow(L1, 2) - pow(L2, 2)) / (2 * L1*L2));
    q1[0] = atan(y / x) - atan((L2*sin(q2[0])) / (L1 + L2 * cos(q2[0])));

    q1_Degrees[0] = (q1[0] * 180) / pi;
    q2_Degrees[0] = (q2[0] * 180) / pi;

    printf_s("q1 is = %.1f q2 is = %.1f\n\n", q1_Degrees[0], q2_Degrees[0]);
}

在此处输入图像描述

标签: cvariablesmathdoublecalculation

解决方案


2个问题

acos()

xinacos(x)需要在范围内[-1...1]。除此之外,结果可能是 NaN。

(pow(x, 2) + pow(y, 2) - pow(L1, 2) - pow(L2, 2)) / (2 * L1*L2)即使在数学上结果应该在范围内,也容易受到计算的轻微影响,导致值刚好在 [-1...1] 之外。

快速解决方法:

double z = (pow(x, 2) + pow(y, 2) - pow(L1, 2) - pow(L2, 2)) / (2 * L1*L2);
if (z < -1.0) z = -1.0;
else if (z > 1.0) z = 1.0;
q2[0] = acos(z);

该问题适用于double, float, long double。它与一种类型“工作”的事实没有理由相信代码对其他值是健壮的。

请注意,代码正在调用double类似的函数acos(), pow(),而不是它们的float对应函数acosf(), powf()double除非您有令人信服的理由,否则我建议始终使用。

晒黑

atan()提供 [-π/2... +π/2] 弧度(又名 [-90...90] 度)结果。

[-π... +π] 弧度(又名 [-180...180] 度)的整圆结果可通过atan2(y,x)

atan((L2*sin(q2[0])) / (L1 + L2 * cos(q2[0])))
// or 
atan2(L2*sin(q2[0]), L1 + L2 * cos(q2[0]))

更好的解决方案是使用不依赖于边缘的不同形式的三角操作acos()。如果 OP 还发布了更高级别的练习目标,则最容易做到。


推荐阅读