Проблема с циклом while, выполняющимся, когда он не должен (c) - PullRequest
0 голосов
/ 17 ноября 2018

Итак, в рамках курса по информатике я немного изучал 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)

I'mновичок в программировании в целом, так что, вероятно, это просто проблема, связанная с тем, что я делаю что-то глупое, но что именно я делаю неправильно, я не знаю.Кто-нибудь сталкивался с этим раньше?

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

Со значениями с плавающей точкой это становится «странным», сравнивая их с другими числами с плавающей запятой, такими как 5, 0,63 и 0,0, потому что ваше значение может фактически быть 0,4999999999 или 0,000000000001, что по существу равно нулю, и в вашем случае не проходит проверку условия и, таким образом,добавляет последний пенни, когда значение затем становится отрицательным.При сравнении чисел с плавающей точкой вы должны учитывать это, сравнивая разницу с небольшим значением эпсилона.

float epsilon = 0.0000001;
if ((f - testVal) < epsilon) {
...
}
0 голосов
/ 17 ноября 2018

Это проблема точности.Равенство с поплавками может быть довольно проблематичным.Хотя в теории f=0, когда вы добираетесь до последнего цикла, это не удается, и он входит в цикл.

Возможный обходной путь - изменить его на некоторое число между 0 и 0.01.Например,

while(f>0.005)

Но лучшим подходом было бы использование типа int для представления денег, каждая единица которой соответствует центу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...