c - While 循环条件不满足

标签 c if-statement while-loop floating-point greedy

<分区>

我有这个功能:

int change(float c)
{
    float coins[] = {0.25, 0.10, 0.05, 0.01};
    int count[] = {0, 0, 0, 0};

    while(c > (0.00))
    {
        printf("I entered here\n");
        if((c-coins[0]) >= (0.00))
        {
            c -= coins[0];
            count[0]++;
            printf("-0.25, c = %.2f\n", c);
        }
        else if((c-coins[1]) >= (0.00))
        {
            c -= coins[1];
            count[1]++;
            printf("-0.10, c = %.2f\n", c);
        }
        else if((c-coins[2]) >= (0.00))
        {
            c -= coins[2];
            count[2]++;
            printf("-0.05, c = %.2f\n", c);
        }
        else if((c-coins[3]) >= (0.00))
        {
            c -= coins[3];
            count[3]++;
            printf("-0.01, c = %.2f\n", c);
        }
    }
    printf("(%d) 25 cents, (%d) 10 cents, (%d) 5 cents, (%d) 1 cents\n",
           count[0], count[1], count[2], count[3]);
    int total = count[0] + count[1] + count[2] + count[3];

    return total;
}

每当我尝试输入 0.06 或 0.07,或任何会导致它到达最后一个 else if 子句(else if((c-coins[3] ) >= (0.00))) 会导致死循环。

而如果我输入 0.25、0.10、0.05 和它们各自的完美倍数,函数运行顺利。 (因为它可能不会到达最后一个 else if 子句)。

所以当我调试时(使用简单的 printf 技术),我发现变量 c 仍然 进入了 while 循环,即使它已达到 0.00。在某些情况下,它甚至会达到 -0.00 或 -0.01(这只有在我将 else if((c-coins[3]) >= (0.00)) 更改为 时才有效否则)。

例子(假设代码中的else if已经是else only):
输入:0.06

c-0.05, c = 0.01
c-0.01, c = -0.00 **<- WTF** 
(0) 25 cents, (0) 10 cents, (1) 5 cents, (1) 1 cents
Total Coins: 2

有人给我解释一下吗?我在这里错过了一些关于 float 的规则吗?或者某些错误是由我的最后一个 else if 子句引起的?

注意:将最后一个 else if 更改为 else 可能有效,但会影响最终答案。此外,将 while 条件更改为 -0.000.001 也不起作用。

最佳答案

浮点值(通常)使用二进制表示。 coins 数组中唯一可以准确 表示的分数是 0.25。所有其他值将略小于或大于正确值。这意味着对这些值的每个算术运算,即使是简单的减法,都会引入小的计算错误,从而导致您的比较和输出错误。

在我看来,最好的解决方案是仅使用整数类型并以美分(百)为单位执行所有计算。您可以使用除法和模数打印出金额。

int change(int cents)
{
   int coins[] = {25, 10, 5, 1};
   int count[] = {0, 0, 0, 0};

   while(cents > 0)
   {
     if((c-coins[0]) >= 0)
     {
        c -= coins[0];
        count[0]++;
        printf("-0.25, c = %d.%02d\n", c/100, c%100);
     }
     /* and so on */

您可能希望根据需要使用unsignedlong 或两者。

关于c - While 循环条件不满足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25341828/

相关文章:

if-statement - COBOL 程序中的语法错误,如果发生意外

java - 将 3D 空间划分为相同大小的 block

javascript - 尝试使用 while 循环打印出用户在第二个输入中写入的次数的输入文本

java - 如何重新启动 while 循环以重新启动游戏?

c - 对 `GlewInit' 的 undefined reference - OpenGL

c - 用于整个 256 位寄存器的 AVX unpackhipd/unpacklopd 模拟

c - 交换矩阵的行后出现 double free() 错误

c - 调用recvmsg后调用epoll_wait()后udp套接字缓冲区变满

javascript - Not not (!!) 在 if 条件内

java - 如何在 `do while` 循环中命令返回顶部?