C:而使用浮点的循环永远不会终止

C:而使用浮点的循环永远不会终止,c,floating-point,precision,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以下的任何其他值,也会发生同样的情况 有人愿意解释一下吗?比较浮点数是否相等是危险的浮点数字本质上是不精确的,因为没有足够的位来表示浮点数字的连续性 任何时候比较floats,都应该比较floats是否在彼此的特定范围内。例

通过执行此代码:

float f = 1.0;
while (f != 0.0) {
    f = f - 0.1;
    printf("%.1f\n", f);
}
预计它将运行10次并停止,但结果是它不可避免地进入堆栈溢出。即使我更改while循环,使f变为1.0以下的任何其他值,也会发生同样的情况


有人愿意解释一下吗?

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

任何时候比较
float
s,都应该比较
float
s是否在彼此的特定范围内。例如:

while ((f - 0.0) > 0.00001)

这是一个浮点问题。尝试
而不是
=

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

为什么代码总是循环

典型的
float
可以准确地表示大约232个数字,
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);
}

最好不要在浮点上执行循环。

它甚至是一些编码标准所要求的,比如FLP30-C规则,在

中,你确定你有堆栈溢出而不是无限循环吗?我在VBA中读到过一篇类似的帖子,在那里通过平方运算解决了负面问题:
if((f*f)>0.00001)/*不等于*/
…没有它,你应该在((f-0.0)时编写
)>0.00001 | |((f-0.0)<-0.00001)
将浮点值与常数进行比较,将浮点值从浮点值中去掉。相对比较更有用。