浮动与c中的双奇怪行为

时间:2014-05-03 10:32:01

标签: c floating-point double

我在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

4 个答案:

答案 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()的参数以弧度表示,而不是度。