Cash.c Ожидаемый 18 / n не 22 / n - PullRequest
0 голосов
/ 05 ноября 2018

Я не могу понять, что не так с моим кодом, но я получаю неправильные значения для простых входных данных, таких как 1 или 2, но правильные входные данные для .41. Если бы кто-то мог помочь мне, это было бы очень признательно!

Это мой код:

#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)

{
    //Establish Variables
    float amount_owed;
    int c = 0;
    //Get Valid Input from User
    do
    {
        amount_owed = get_float ("Change Owed: ");
    }   while (amount_owed <= 0);

    //Check for quarters, mark  # of quarters that can be used, subtract value from original amount_owed
    do
    {
        (c++);
        (amount_owed = amount_owed - .25);
    }   while (amount_owed >= .25);

    //Check for dimes, mark # of dimes that can be used, subtract value from original amount_owed

    do
    {
        (c++);
        (amount_owed = amount_owed - .1);
    }   while ((amount_owed >= .1) && (amount_owed < .25));

    //Check for Nickels, mark $ of nickels that can be used, subtract value from original amount_owed

    do
    {
        (c++);
        (amount_owed = amount_owed - .05);
    }   while ((amount_owed >= .05) && (amount_owed < .1));

    //Check for Pennies, mark # of pennis that can be used, subtract value from original amount_owed

    do
    {
        (c++);
        (amount_owed = amount_owed - .01);
    }   while ((amount_owed >= .01) && (amount_owed < .05));
    //Print Number of Minimum number of coins that can be used

    {
       if (amount_owed == 0)
       ;
        printf("%d\n", c);
    }
}

1 Ответ

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

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

А пока предположим, что значение float действительно точное.

Когда вы пишете:

do
{
    c++;
    ...
} while(...);

код в теле будет всегда выполняться хотя бы один раз .

То есть, с вашим кодом, если ввод 1.0, первый цикл будет выполнен 4 раза, а amount_owed будет 0.0.

Когда в течение следующих 3 do-while вы все равно войдете в тело один раз и выполните c++ (даже если amount_owed равно нулю). Следовательно, вы получите 7 вместо 4 (4 из первого цикла + 1 из каждого из трех следующих циклов).

Решение заключается в использовании обычного while вместо do-while. Как:

#include <stdio.h>

int main(void) {
    float amount_owed = 1.0;
    int c = 0;

    while (amount_owed >= 0.25)
    {
        c++;
        amount_owed = amount_owed - 0.25;
    }

    while ((amount_owed - 0.1) >= 0)
    {
        c++;
        amount_owed = amount_owed - 0.1;
    }

    while (amount_owed >= .05)
    {
        c++;
        amount_owed = amount_owed - .05;
    }

    while (amount_owed >= .01)
    {
        c++;
        amount_owed = amount_owed - .01;
    }

    printf("%d\n", c);

    return 0;
}

Вернуться к использованию float : числа с плавающей точкой не могут представлять каждое число с точностью до 100%. Поэтому при выполнении вычислений с использованием чисел с плавающей точкой вы, скорее всего, увидите некоторые ошибки округления. Поэтому для любого вычисления, которое требует точного результата, вы должны попытаться сделать это, используя целые числа.

Для такой задачи «хитрость» состоит в том, чтобы считать amount_owed находящимися в единицах наименьших монет, которые у вас есть. Как правило, это означает 100 раз «нормальный» способ мышления об этом. Например, вместо 1.17 вы используете 117.

Тогда ваш код может быть больше похож на:

#include <stdio.h>

int main(void) {
    unsigned amount_owed = 100;  // note 100 instead of 1.0
    int c = 0;

    while (amount_owed >= 25)  // note 25 instead of .25
    {
        c++;
        amount_owed = amount_owed - 25;
    }

    while ((amount_owed - 10) >= 0)
    {
        c++;
        amount_owed = amount_owed - 10;
    }

    . . . 
...