while 循环在不应该执行时出现问题 (c)

Issue with while loop executing when it shouldn't (c)

因此,作为计算机科学课程的一部分,我一直在学习一些 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 returns 是一个正确的值,而 $0.15 导致最后一个 while 循环无缘无故地增加一分钱。

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

(有问题的 while 循环)

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

这是一个精度问题。与浮点数相等可能会出现问题。尽管理论上 f=0 当你到达最后一个循环时,这会失败,并进入循环。

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

while(f>0.005)

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

对于浮点值,它会 "weird" 将它们与其他浮点数(例如 5、0.63 和 0.0)进行比较,因为您的值实际上可能是 0.4999999999 或 0.000000000001,这实际上是零,并且在您的情况下失败条件测试,从而在该值真正变为负值时添加最后一分钱。比较浮点数时,您必须通过将差异与某个小的 epsilon 值进行比较来说明这一点。

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