c - 使用浮点数时计算错误
问题描述
我正在尝试进行计算,由于某种原因,当我使用 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]);
}
解决方案
2个问题
acos()
x
inacos(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 还发布了更高级别的练习目标,则最容易做到。
推荐阅读
- python - 烧瓶线程池耗尽
- python - 如何将图像裁剪为例如形状。在 Discord.py 中使用 Pillow 圈?
- math - 从平面法线计算 Z 值
- python - 查找给定数据的日期(文本中:例如 2019 年 2 月 8 日)
- java - 将平面 JSON 数组转换为 JAVA 中的结构化形式
- flutter - 通过添加两个不同的列表生成第三个列表
- javascript - 无法使用 useState() 设置值
- apache-kafka - kafka中的多行消息
- javascript - 脚本已加载,但无法调用其任何函数
- python - 使用 Image Data Generator 在训练中执行 10 折交叉验证