为什么“for(i = 0.1; i!= 1.0; i + = 0.1)”在i = 1.0时不会中断?

我今天参加了C考试,我被问到类似的问题:

这个程序有什么问题:

for( x = .1 ; x != 1.0 ; x += .1) printf("%f\n", x); 

我无法解决它,因为我必须写一些我标记为.1的错误。 但是,当我回到家里时,我运行这个程序,结果certificate当x等于1.0并且陷入无限循环时它不会中断:

 $ cat exam.c #include  int main(int argc, char **argv) { float x; for(x = .1 ; x != 1.0 ; x += .1) printf("%f\n", x); return 0; } $ gcc exam.c -o exam $ ./exam 0.100000 0.200000 0.300000 0.400000 0.500000 0.600000 0.700000 0.800000 0.900000 1.000000 <- ? 1.100000 1.200000 1.300000 1.400000 1.500000 .... 

有人可以解释为什么会这样。

这是家庭作业的典型问题。

问题是0.1不能精确地存储在浮点数中,检查<= 1.0

然而, 这只适用于非常有限的范围,如Cthulhu说。 我完全错过了这个问题。 因为最好使用int并在以后划分它的值

<=或<不是解决方案!

在循环中使用浮点并非没有问题。 舍入误差累积。 即使使用<= ,循环也可能无法运行正确的次数。

它适用于<=1.0 (10次) ,但运行时间少于预期的<=50.0 (499次)

  for(i = 0.1 ; i <= 50.0 ; i += 0.1) { ... }//runs 499 times, not 500! 

如果遇到这个问题,这个问题可能不容易被发现。 在比较之前对其进行舍入舍入函数 )可能有所帮助,但唯一可靠的解决方案是......

在循环中使用整数作为控制变量。

永远不要使用!=for循环中,当你的循环变量永远不会达到你期望的值时,它会导致很难找到错误。 总是使用<而不是。

这是由于IEEE浮点标准。 检查维基百科

 0.1 + 0.2 = 0.3 => FALSE - Expected: 0.3 | Real: 0.30000000000000004 

在这里查看真实(JavaScript)演示: http : //k8.no-ip.org/stackoverflow/13542220.htm

0.1不能精确存储在浮点数中。 浮点数包含近似值,您尝试将其均衡为精确值。

建议,每次需要循环时都使用整数

 int x; float y = 0; for( x = 1; x < 11; x += 1){ y += 0.1; printf("%f\n", y); } 

或者您也可以使用它:

 for( x = 1; x < 11; x += 1){ printf("%f\n", ( x / 10.0 ) ); } 

在这两种情况下,您都将循环值保持为整数。