C中带有浮点数的现金分配错误

时间:2019-05-14 12:17:04

标签: c floating-point int division

我目前正在研究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 个答案:

答案 0 :(得分:4)

在您的C实现中,这些行:

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

dime设置为0.100000001490116119384765625,将nickel设置为0.0500000007450580596923828125,并将penny设置为0.00999999977648258209228515625。这导致每个硬币的计算量略有偏差。此外,change在处理每个硬币后的计算都有舍入误差。

要解决此问题,请在将changeget_float一起使用后,使用以下命令将其转换为美分:

int cents = roundf(change * 100);

然后使用整数算术执行所有计算。 (包括<math.h>以获得roundf的声明。)

答案 1 :(得分:1)

从这一行开始:

#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;
}

其余的应该很容易;)

答案 2 :(得分:0)

仅是一个建议,为什么不使用整数算术执行所有计算?将浮点数“ 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。

您可能还想检查用户是否输入了他们认为是美元而不是整数的美分的十进制(浮动)金额。但这超出了这个问题的范围。