我在C中实施一个简单的训练程序时遇到麻烦。程序应该计算一个角度的随机余弦或窦,打印问题“计算角度x的余弦/窦”给用户,谁应该键入右边以“factor sqrt(value)”的形式回答。即对于cos(0),用户应键入1,对于sin(45),用户应键入0.5sqrt(2)
。大多数代码都在此任务中给出。该程序无法正常工作 - 对于cos(270),正确的答案是-0.000。为什么会这样?为什么这段代码不会尖叫“除以0”?此外,根据任务描述,变量right
应为类型double
的{{1}}和rueckgabe
类型。但是当我使用double而不是float时,我只会获得非常高的值(如21234或-435343)。如果我使用int作为get_user_input()的返回值,该程序将无法正常工作,对吧?
以下是代码:
int
答案 0 :(得分:3)
在你的程序中,除数和被除数可以同时接近/正好为0。
你的程序没有给你一个“除零” - 错误,因为默认情况下,大多数浮点实现默默地给你无穷大/ NaN / 0 / -0,具体取决于你划分的确切值。
答案 1 :(得分:3)
浮点运算中270°的余弦并不完全为零,因为270°无法用弧度精确表示。
下表显示270°(中间行)的余弦值以及相邻32位浮点数的余弦值的第一行和最后一行:
phi cos(phi)
4.7123885 -0.0000004649123
4.712389 0.000000011924881
4.7123895 0.00000048876205
对于64位双精度浮点数也是如此:
phi cos(phi)
4.712388980384689 -1.0718754395722282e-15
4.71238898038469 -1.8369701987210297e-16
4.712388980384691 7.044813998280222e-16
使用当前的浮点精度,1.5 * pi附近的cos(phi)
phi
无法正好为零。
你可以通过编写一个以{度为单位的cosdeg
来修复它,并返回余弦和正弦为-1,0或1的角度的精确值,否则用弧度计算值。 (然后会很乐意地将所需的除法产生为零。)
答案 2 :(得分:3)
由于正弦和余弦返回的值在[-1,1]范围内,因此我建议你使用绝对误差而不是相对误差。通过替换
correct = fabs(get_user_input(is_cos, angle)/right - 1.) <= ACCURACY;
与
correct = fabs(get_user_input(is_cos, angle) - right) <= ACCURACY;
一切都应该按预期工作。
一般来说,我倾向于对较大值使用相对误差,对较小值使用绝对误差。您可以将两者结合使用
fabs(a-b)/(1.0+min(fabs(a), fabs(b)))
(假设你有min
的合理定义)倾向于大值的相对误差和小值的绝对误差。
答案 3 :(得分:0)
sin()和cos()的参数以弧度表示,而不是度。