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() чтобы избежать двойного искажения точности данных.

Другие вопросы по тегам