C:使用浮点的while循环永不终止

时间:2019-03-22 16:41:13

标签: c floating-point precision

通过执行以下代码:

float f = 1.0;
while (f != 0.0) {
    f = f - 0.1;
    printf("%.1f\n", f);
}

预计它将运行10次并停止,但结果是它不可避免地会进入堆栈溢出。即使我更改while循环,使f达到1.0以下的任何其他值,也会发生同样的情况。

有人在乎解释吗?

4 个答案:

答案 0 :(得分:3)

比较浮点数是否相等是很危险的。 float数字本质上是不精确的,因为没有足够的位数来表示float数字的连续性质。

每次比较float时,都应该比较float在彼此的一定范围内。例如:

while ((f - 0.0) > 0.00001)

答案 1 :(得分:2)

为什么代码会永远循环?

典型的float可以准确表示大约2 32 个数字,0.1不是其中之一。所以代码更像。

float f = 1.0;
while (f != 0.0) {
  f = f - a_number_close_to_one_tenth;
  printf("%.1f\n", f);
}

重复的减法“未命中” 0.0。


请改为使用>=,然后代码将迭代预期的次数(或可能再重复一次)。使用更高精度的打印来查看原因。

float f = 1.0;
while (f >= 0.0) {
  f = f - a_number_close_to_one_tenth;
  printf("%.17e\n", f);
}

答案 2 :(得分:1)

这是一个浮点问题。尝试使用>代替!=

float f = 1.0;
while (f > 0.0) {
    f = f - 0.1;
    printf("%.1f\n", f);
}

答案 3 :(得分:0)

最好不要在浮点上进行循环。
某些编码标准(例如规则https://wiki.sei.cmu.edu/confluence/display/c/FLP30-C.+Do+not+use+floating-point+variables+as+loop+counters

中的规则FLP30-C甚至都需要这样做)