Greedy.c выводит неправильный номер, и я понятия не имею, почему? (Код CS50)
Я работаю над программой, чтобы вычислить наименьшее количество монет для суммы изменений, предоставленных пользователем.
Он предназначен для проверки значений 0,25, 0,10, 0,05 и 0,01. Если значение пользователя больше или равно одному из них (в наборе последовательных операторов if), к счету монет добавляется дополнительная монета, и эта сумма отбирается у исходного номера пользователя.
Затем, когда номер пользователя меньше 0,01, программа должна завершиться и распечатать счет монет.
Я прочитал этот код несколько раз и пытался его исправить, но не вижу проблемы, можете ли вы помочь мне с этим?
0.25 показывает 1 монету (правильно), но 0.26 показывает 1 монету (неправильно), по какой-то причине пропущено мое утверждение "позже".
2 блока кода, контролирующего 0,25 и 0,01, копируются и вставляются за исключением значения монеты, так что же происходит?
Спасибо, Раису
#include <stdio.h>
#include <cs50.h>
int main (void)
{
/**
* Declare all variables
*/
float UserInput = 0.00;
float Coin1 = 0.25;
float Coin2 = 0.10;
float Coin3 = 0.05;
float Coin4 = 0.01;
int CoinCount = 0;
/**
* Ask user for change amount and check it is more than 0, then print it
*/
do
{
printf("Please put the amount of change, in the format 0.00\r\n\r\n");
UserInput = GetFloat();// Get a float, check format
}
while (UserInput <0 || UserInput == 0);
printf ("You have entered %f\r\n\r\n",UserInput);
/**
* If userinput is over or equal to 0.25, take off 0.25 and add 1 to the coin count
*/
if (UserInput>=0.25)
{
do
{
UserInput -= Coin1;
CoinCount +=1;
}
while (UserInput >= Coin1);
printf ("\r\n%i of %f Pieces\r\n",CoinCount,Coin1);
}
/**
* If userinput is over or equal to 0.10, take off 0.10 and add 1 to the coin count
*/
if (UserInput >=0.10)
{
do
{
UserInput -= Coin2;
CoinCount +=1;
}
while (UserInput >= Coin2);
printf ("\r\n%i of %f Pieces\r\n",CoinCount,Coin2);
}
/**
* If userinput is over or equal to 0.05, take off 0.05 and add 1 to the coin count
*/
if (UserInput >=0.05)
{
do
{
UserInput -= Coin3;
CoinCount +=1;
}
while (UserInput >= Coin3);
printf ("\r\n%i of %f Pieces\r\n",CoinCount,Coin3);
}
/**
* If userinput is over or equal to 0.01, take off 0.01 and add 1 to the coin count
*/
if (UserInput >=0.01)
{
do
{
UserInput -= Coin4;
CoinCount +=1;
}
while (UserInput >= Coin4);
printf ("\r\n%i of %f Pieces\r\n",CoinCount,Coin4);
}
printf("\r\nTotal Coins Needed: %i\r\n*********************\r\n\r\n\r\n",CoinCount);
}
2 ответа
Я написал эту небольшую программу, чтобы проиллюстрировать проблему, заключающуюся в том, что формат с плавающей запятой не может точно хранить все значения.
#include <stdio.h>
int main(void){
float UserInput;
int UserCents;
printf("Please put the amount of change, in the format 0.00\n");
if (scanf("%f", &UserInput) != 1)
return 1;
UserCents = (int)(UserInput * 100 + 0.5);
printf("Dollars = %.15f\n", UserInput);
printf("Cents = %d\n", UserCents);
return 0;
}
Сессия программы:
Please put the amount of change, in the format 0.00
12.34
Dollars = 12.340000152587891
Cents = 1234
Итак, у вас есть две возможности: 1) перейти на использование int
или 2) сравните значения с плавающей запятой с допустимым отклонением. Никогда не сравнивайте их на равенство.
Я изменил ваш код. который работает нормально. (Я пытался с несколькими входами).
int main (void)
{
/**
* Declare all variables
*/
double UserInput = 0.00;
double Coin1 = 0.25;
double Coin2 = 0.10;
double Coin3 = 0.05;
double Coin4 = 0.01;
int TotalCoinCount = 0;
int CoinCount = 0;
/**
* Ask user for change amount and check it is more than 0, then print it
*/
do
{
printf("Please put the amount of change, in the format 0.00\r\n\r\n");
//UserInput = GetFloat();// Get a float, check format
cin >> UserInput;
}
while (UserInput <0 || UserInput == 0);
printf ("You have entered %f\r\n\r\n",UserInput);
UserInput = floorf(UserInput * 100) / 100;
/**
* If userinput is over or equal to 0.25, take off 0.25 and add 1 to the coin count
*/
if (UserInput>=0.25)
{
do
{
UserInput -= Coin1;
UserInput = floorf(UserInput * 100) / 100;
CoinCount +=1;
}
while (UserInput >= Coin1);
printf ("\r\n%i of %f Pieces\r\n",CoinCount,Coin1);
}
TotalCoinCount += CoinCount;
CoinCount = 0;
/**
* If userinput is over or equal to 0.10, take off 0.10 and add 1 to the coin count
*/
if (UserInput >=0.10)
{
do
{
UserInput -= Coin2;
UserInput = floorf(UserInput * 100) / 100;
CoinCount +=1;
}
while (UserInput >= Coin2);
printf ("\r\n%i of %f Pieces\r\n",CoinCount,Coin2);
}
TotalCoinCount += CoinCount;
CoinCount = 0;
/**
* If userinput is over or equal to 0.05, take off 0.05 and add 1 to the coin count
*/
if (UserInput >=0.05)
{
do
{
UserInput -= Coin3;
UserInput = floorf(UserInput * 100) / 100;
CoinCount +=1;
}
while (UserInput >= Coin3);
printf ("\r\n%i of %f Pieces\r\n",CoinCount,Coin3);
}
TotalCoinCount += CoinCount;
CoinCount = 0;
/**
* If userinput is over or equal to 0.01, take off 0.01 and add 1 to the coin count
*/
if (UserInput >=0.01)
{
do
{
UserInput -= Coin4;
UserInput = floorf(UserInput * 100) / 100;
CoinCount +=1;
}
while (UserInput >= Coin4);
printf ("\r\n%i of %f Pieces\r\n",CoinCount,Coin4);
}
TotalCoinCount += CoinCount;
CoinCount = 0;
printf("\r\nTotal Coins Needed: %i\r\n*********************\r\n\r\n\r\n",TotalCoinCount);
}
я изменился float
в double
и использовал floorf()
чтобы избежать двойного искажения точности данных.