4

我为我的作业编辑了一个 C 程序,以前没有类型转换,迭代在 i=1 处停止,现在类型转换在 i=6 处停止。

任何想法为什么?提前致谢!

int main(void)
{

    int i = 0;
    double d = 0.0;

    while ( (i == (int) (d * 10)) && (i < 10) )
    {
        i = i + 1;
        d = (double) (d + 0.1);
        printf("%d %lf\n", i, d);
    }

    printf("%d %lf\n", i, d);

    getch();

    return 0;
}
4

3 回答 3

4

浮点运算是不精确的。该值0.1不能以二进制浮点数精确表示。这里推荐的阅读是:每个计算机科学家都应该知道的关于浮点运算的知识

在程序的某个时刻,由于舍入误差而d变得略小于,因此您的循环终止。i/10

于 2012-09-06T14:01:12.390 回答
2

除了其他答案之外,我还想回答为什么循环以 conditioni == (d * 10)比 with更早终止的问题i == (int) (d * 10)

在第一种情况下,int左边的==值被提升为加倍,因此当累积误差d*10为正或负时(例如 0.999999 或 1.000001),就会发生不等式。

在第二种情况下,右侧被截断为 int,因此不等式仅在错误为负时发生(例如 5.999999)。因此,第一个版本会提前失败。

于 2012-09-06T14:13:56.663 回答
1

如前所述,这不起作用的原因是二进制浮点数不能代表所有十进制浮点二进制数,这是不可能的。要了解更多信息,请查看这篇非常棒的文章:

每个程序员都应该知道的关于浮点运算的知识

现在,在更实际的方面,当使用浮点并将其与另一个数字进行比较时,您应该几乎总是round使用该值或使用 epsilon 值,如下所示:

if (ABS(doubleValue - intValue) < 0.00001) // 0.00001 is a margin-of-error for floating point arithmetic
    // the two numbers are even (or close to it)
于 2012-09-06T14:06:20.627 回答