【问题标题】:Issue with while loop executing when it shouldn't (c)不应该执行 while 循环的问题 (c)
【发布时间】:2018-11-17 00:53:02
【问题描述】:

因此,作为计算机科学课程的一部分,我一直在学习 C 语言。其中一个挑战是创建一个程序,告诉假设的收银员需要多少硬币才能将零钱兑换成顾客。我用一组while循环完成了这个,整个程序看起来像这样:

#include <stdio.h>
#include <cs50.h>

int main(void)
{
    float f;
    int i;
    i=0;
do
{
    f = get_float("Input Change: \n");
}
while(f<0);
// This do-while loop uses a get_float operator to get a postive input from the user.
while(f>=0.25)
{
f=f-0.25;
i=i+1;
}
// Each one of these loops represents using one kind of coin. For this one, every time it runs it adds
// one coin to the final tally and removes 25 cents from the change owed.
while(f>=0.10)
{
f=f-0.10;
i=i+1;
}
// Dime loop, subtracts ten from change owed.
while(f>=0.05)
{
f=f-0.0500000;
i=i+1;
}
// Nickel loop, subtracts five from change owed.
while(f>0)
{
f=f-0.01;
i=i+1;
}
// Penny loop, subtracts one from change owed.
printf("You need %i coins.%f\n", i, f);
//This just prints the number of coins needed.
}

问题在于,即使没有理由这样做,我们也会随机执行最后一个 while 循环。例如,$0.42 返回一个正确的值,而 $0.15 会导致最后一个 while 循环无缘无故地增加一分钱。

while(f>0)
{
f=f-0.01;
i=i+1;
}

(有问题的while循环)

一般来说,我是编程新手,所以这可能只是我做了一些愚蠢的事情造成的问题,但我不知道我到底做错了什么。有人遇到过这个吗?

【问题讨论】:

  • 首先,相同的输入是否总是产生相同的输出?其次,尝试在每次迭代中打印f 的值,我怀疑你有浮点舍入错误。也许使用整数来表示整分会让数学变得更容易。
  • 使用不可移植的非标准 C 头文件是一种糟糕的编程习惯。如果你在一个班级,那么这是可以接受的,只要记住头文件:`cs50.h 是不可移植的。
  • 一般来说,将float 用于货币值是非常危险的,因为float 并不总是产生100% 正确的值。
  • 或:为了便于阅读和理解:1) 请始终缩进代码。在每个左大括号“{”后缩进。在每个右大括号 '}' 之前取消缩进。建议每个缩进级别为 4 个空格。 2)单独的代码块:forifelsewhiledo...whileswitchcasedefault通过单个空行

标签: c while-loop cs50


【解决方案1】:

这是一个精度问题。浮点数的平等可能是相当有问题的。即使理论上f=0 当你到达最后一个循环时,它也会失败,它会进入循环。

一种可能的解决方法是将其更改为介于00.01 之间的某个数字。例如

while(f>0.005)

但更好的方法是使用类型int 来表示货币,每个单位对应一美分。

【讨论】:

    【解决方案2】:

    对于浮点值,将它们与其他浮点数(例如 5、0.63 和 0.0)进行比较会变得“奇怪”,因为您的值实际上可能是 0.4999999999 或 0.000000000001,基本上为零,在您的情况下,条件测试失败,因此当值真正变为负数时,添加最后一分钱。在比较浮点数时,您必须通过将差异与一些小的 epsilon 值进行比较来解释这一点。

    float epsilon = 0.0000001;
    if ((f - testVal) < epsilon) {
    ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-11
      • 1970-01-01
      • 1970-01-01
      • 2015-06-19
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多