这个循环条件出了什么问题?

时间:2014-01-24 20:03:43

标签: c

查看this link的输出(向下滚动以查看输出)以找出我想要完成的内容

问题在于第9-11行的for循环

for(i=0; i<=0.9; i+=0.1){
  printf("%6.1f ",i);
}

我预计这会打印从0.0到0.9的值,但在打印0.8后会停止,任何想法为什么?

5 个答案:

答案 0 :(得分:7)

在这里使用float是问题的根源。相反,用int:

来做
int i;
for(i = 0; i <= 10; i++)
   printf("%6.1f ", (float)(i / 10.0));

输出:

0.0    0.1    0.2    0.3    0.4    0.5    0.6    0.7    0.8    0.9    1.0 

答案 1 :(得分:4)

添加作为答案,因为没有足够的声誉来评论。

理想情况下,浮点不应该用于迭代,但是如果你想知道为什么要更改你的代码并看看如何。

for(float i=0; i<=0.9f; ){
    i+=0.1f;
    System.out.println(i);
}

结果如下。

0.1
0.2
0.3
0.4
0.5
0.6
0.70000005
0.8000001
0.9000001

你的第9个值超过0.9。

答案 2 :(得分:1)

浮点运算在计算中是不精确的。这是因为计算机表示浮点值的方式。以下是关于该主题的MSDN文章的摘录:

  

每个十进制整数可以用二进制整数精确表示;然而,对于分数而言,这不是真的。实际上,在基数小于10的任何系统中,基数10中每个不合理的数字也都是不合理的。

     

对于二进制,特别地,只有可以以p / q形式表示的分数,其中q是2的整数幂,可以用有限的比特数精确地表示。

     

即使是常见的小数部分,例如十进制0.0001,也无法在&gt;二进制中精确表示。 (0.0001是一个周期为104位的重复二进制小数!)

链接到完整文章:https://support.microsoft.com/kb/42980

答案 3 :(得分:1)

浮点数不能精确地表示小数,因此舍入错误会累积:

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    float literal = 0.9;
    float sum = 0;
    for(int i = 0; i < 9; i++)
        sum += 0.1;

    cout << setprecision(10) << literal << ", " << sum << endl;
    return 0;
}

输出:

0.8999999762, 0.9000000954

答案 4 :(得分:0)

你循环是正确的,但循环中的浮点比较是不安全的。 问题是binary floating point number cannot exactly represent 0.1

这样可行。

    for(i=0.0; i<=0.9001; i+=0.1){
           printf("%6.1f ",i);