为什么变量 c 在应该打印 4 时打印为 3?

Why does the variable c print as 3 when it should print 4?

X 是一个小数,它进入一堆循环,不断从中减去某些小数,而 c 是一个整数,每次操作发生时都会递增 1。应该发生四个操作,但最后一个循环提前终止并且 c 永远不会从 3 递增到 4。最后一个 while 循环总是提前终止?

int main(void) {

float x = 0.41;

int c = 0;

while(x >= 0.25)
{
    x-= 0.25;

    c++;
}

while(x >= 0.1)
{
    x-= 0.1;

    c++;
}

while(x >= 0.05)
{
    x-= 0.05;

    c++;
}

while(x >= 0.01)
{
    c++;

    x-= 0.01;
}

printf("%i", c);

}
while(x >= 0.05)
{
    x-= 0.05;
    c++;
}

while(x >= 0.1)
{
    c++;
    x-= 0.01;
}

尝试将这些切换为这些

while(x >= 0.1)
{
    c++;
    x-= 0.01;
}
while(x >= 0.05)
{
    x-= 0.05;
    c++;
}

C 中的浮点数不是绝对精确的。它们有 23 位来实际表示实际值。当你写

float x = 0.41

浮点值的实际表示与exactly0.41略有不同,具体取决于您的计算机architecture/compiler。

要亲自查看,请将以下行添加到每个循环块中:

printf("%d, %.30f\n", c, x);

在我的机器上,我得到

1, 0.159999999999999975575093458247
2, 0.059999999999999970023978335121
3, 0.009999999999999967248420773558

在 C 中与浮点数的比较应使用 epsilon 值来处理这些差异。在您的情况下,您应该允许比较值在目标值的范围内。像

#include <math.h>
...
while(fabs(x-0.01f) < 0.000001) //check that x is within a certain range of 0.01 

参考题目:http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

精确比较不能与有限精度混合。如果您用一定数量的小数位 (0.3333333) 表示 1/3,这完全是相同的原因,您需要将它添加到零 4 次才能大于或等于 1 .