通过执行以下代码:
float f = 1.0;
while (f != 0.0) {
f = f - 0.1;
printf("%.1f\n", f);
}
预计它将运行10次并停止,但结果是它不可避免地会进入堆栈溢出。即使我更改while循环,使f达到1.0以下的任何其他值,也会发生同样的情况。
有人在乎解释吗?
答案 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