ошибка деления наличных в C с плавающей точкой - PullRequest
1 голос
/ 14 мая 2019

В настоящее время я работаю над проблемой «наличных» cs50: оцениваю количество монет, необходимое для внесения некоторых изменений.

Например: $ 0,41 задолженность = 1 квартал, 1 цент, 1 никель, 1 пенни.

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

Я включил несколько операторов printf, чтобы попытаться отследить, что я мог делать, но я не могу понять, почему не работает подразделение.

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    // change
    float change = get_float("how much change is owed?: ");
    int coins = 0;

    //reprompt
    while (change < 0)
    {
        change = get_float("how much change is owed?: ");
    }

    //quarter
    float quarter = 0.25;
    float quarters = change / quarter;
    quarters = (int) quarters;
    change = change - (quarters * quarter);

    printf("%f quarters\n", quarters);

    //dimes
    float dime = 0.10;
    float dimes = change / dime;
    dimes = (int) dimes;
    change = change - (dimes * dime);

    printf("%f dimes\n", dimes);

    //nickels
    float nickel = 0.05;
    float nickels = change / nickel;
    nickels = (int) nickels;
    change = change - (nickels * nickel);

    printf("%f nickels\n", nickels);
    printf("%f in change left change\n", change);

    //pennies
    float penny = 0.010000;
    float pennies = change / penny;
    pennies = (int) pennies;
    change = change - (pennies * penny);

    printf("%f pennies\n", pennies);

    //coins
    coins = quarters + dimes + nickels + pennies;
    printf("%i\n", coins);

    //printf("%f\n", change);
}

Ответы [ 3 ]

4 голосов
/ 14 мая 2019

В вашей реализации C эти строки:

float dime = 0.10;
float nickel = 0.05;
float penny = 0.010000;

устанавливает dime до 0,100000001490116119384765625, nickel до 0,0500000007450580596923828125 и penny до 0,00999999977648258209228515625.Это приводит к тому, что расчет для каждой монеты слегка отклоняетсяКроме того, вычисления change после обработки каждой монеты имеют ошибки округления.

Чтобы исправить это, после получения change с get_float, конвертируйте его в число центов с помощью:

int cents = roundf(change * 100);

Затем выполните все вычисления с целочисленной арифметикой.(Включите <math.h>, чтобы получить объявление roundf.)

1 голос
/ 14 мая 2019

Начните с этой строки:

#include <math.h>


#define PENNIES_IN_GBP (100)


int main(void)
{
        int change_pn = roundf(PENNIES_IN_GBP * get_float("how much change is owed?: "));

        /* ... */

        return 0;
}

Остальное должно быть легко;)

0 голосов
/ 14 мая 2019

Просто предложение, почему бы не выполнить все вычисления в целочисленной арифметике?Конвертируем число с плавающей точкой «change» в целое число «cents»

(int) cents = roundf(100.0 * change); // see comments below answer

, а затем сохраняем все как целые числа, например

//quarter
const int quarter = 25;
int quarter_count = cents / quarter;
cents = cents % quarter; // use modulus operator

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

Поскольку вы никогда не захотите изменять количество центов в квартале (особенно случайно), вы можете объявить его как const int.

Возможно, вы также захотите проверить, что пользователь ввелдесятичная (плавающая) сумма, которую они считают долларами, а не целым числом центов.Но это выходит за рамки этого вопроса.

...