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

带浮点数的C中的现金分割错误,c,floating-point,int,division,cs50,C,Floating Point,Int,Division,Cs50,我目前正在处理cs50的现金问题:估计需要支付一些零钱的硬币数量 例:欠0.41美元=1个25美分,1个一角硬币,1个五分镍币,1便士 然而,当估计所需硬币的数量时,我认为是由于我自己的错误,因为它似乎总是减少一到两个硬币 我已经包括了多个printf语句,试图跟踪我可以做什么,但我似乎不明白为什么部门不工作 #include <cs50.h> #include <stdio.h> int main(void) { // change float cha

我目前正在处理cs50的现金问题:估计需要支付一些零钱的硬币数量

例:欠0.41美元=1个25美分,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);
}
从这行开始:

#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;
}
剩下的应该很简单

从这行开始:

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

剩下的应该很简单

在C实现中,这些行:

float dime = 0.10;
float nickel = 0.05;
float penny = 0.010000;
将dime设置为0.1000000149011919384765625,将NIKE设置为0.050000007450580596923828125,将penny设置为0.00999977648258209228515625。这导致每枚硬币的计算结果略有偏差。此外,处理每枚硬币后的变化计算有舍入误差

要解决此问题,请在使用get_float获得更改后,使用以下命令将其转换为美分:

int cents = roundf(change * 100);

然后使用整数运算执行所有计算。Include以获取roundf声明。

在您的C实现中,以下几行:

float dime = 0.10;
float nickel = 0.05;
float penny = 0.010000;
将dime设置为0.1000000149011919384765625,将NIKE设置为0.050000007450580596923828125,将penny设置为0.00999977648258209228515625。这导致每枚硬币的计算结果略有偏差。此外,处理每枚硬币后的变化计算有舍入误差

要解决此问题,请在使用get_float获得更改后,使用以下命令将其转换为美分:

int cents = roundf(change * 100);

然后使用整数运算执行所有计算。Include以获得roundf的声明。

只是一个建议,为什么不使用整数算术执行所有计算?将浮点更改转换为整数

(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
我还要恭敬地建议,使用非常相似的变量名称,例如quarter和quarter,可能会导致错误

由于您永远不希望在一个季度内更改美分的数量,特别是在偶然情况下,您可以将其声明为const int


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

只是一个建议,为什么不用整数算法执行所有的计算呢?将浮点更改转换为整数

(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
我还要恭敬地建议,使用非常相似的变量名称,例如quarter和quarter,可能会导致错误

由于您永远不希望在一个季度内更改美分的数量,特别是在偶然情况下,您可以将其声明为const int


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

您是否尝试过检查?是的,但是他们的内置帮助功能无法帮助我。您可能遇到以下问题:int0.99999==0。浮点运算非常棘手。您可以只使用整数运算来解决这个问题,将便士作为基本单位。我建议您在这个任务中不要使用浮点运算。只需使用int来记录硬币的数量。所以一角硬币不是0.1,而是10,等等。printf语句无法显示正确的值。%f将值舍入到小数点后的六位数字。显示完整值%.99g在这些情况下就足够了,如果您的C实现格式正确,%a将使用十六进制浮点格式显示精确值。您是否尝试检查?是的,但是其内置帮助函数无法帮助我。您可能遇到以下问题:int0.99999==0。浮点运算非常棘手。您可以只使用整数运算来解决这个问题,将便士作为基本单位。我建议您在这个任务中不要使用浮点运算。只需使用int来记录硬币的数量。所以一角硬币不是0.1,而是10,等等。printf语句无法显示正确的值。%f将值舍入到小数点后的六位数字。显示完整值%.99g在这些情况下就足够了,如果您的C实现格式正确,%a将使用十六进制浮点格式显示精确值。roundf将舍入为整数美元,丢失美分数。roundf将舍入为整数美元,丢失美分数。int 100.0*更改;是错误的,因为更改可能小于所需的值。例如,如果用户输入“.41”,则更改将为40.9999964237213134765625,100.0*更改将为40.9999964237213134765625,这将导致应为41的美分为40。@Eric Postpuschill-足够公平。
它应该是int 100.0*change+0.5;对于输入“.41”,int 100.0*变化+0.5产生90,对于41+/-0.5范围内的任何变化值,将四舍五入到41。您需要100*零钱+0.5。但是没有必要拼凑自己的舍入函数。该库具有相应的函数,例如roundf和lroundf.OK,Eric,point take。我已经有很长一段时间没有愤怒地写C了,我忘记了那些函数。我相信,在1999年该回合开始之前的几天里,我们就是这样做的。在任何情况下,我的答案的要点是,最好用整数算法进行计算,避免浮点到整数的转换和舍入错误。就连我也陷入了困境!int 100.0*变化;是错误的,因为更改可能小于所需的值。例如,如果用户输入“.41”,则更改将为40.9999964237213134765625,100.0*更改将为40.9999964237213134765625,这将导致应为41的美分为40。@Eric Postpuschill-足够公平。它应该是int 100.0*change+0.5;对于输入“.41”,int 100.0*变化+0.5产生90,对于41+/-0.5范围内的任何变化值,将四舍五入到41。您需要100*零钱+0.5。但是没有必要拼凑自己的舍入函数。该库具有相应的函数,例如roundf和lroundf.OK,Eric,point take。我已经有很长一段时间没有愤怒地写C了,我忘记了那些函数。我相信,在1999年该回合开始之前的几天里,我们就是这样做的。在任何情况下,我的答案的要点是,最好用整数算法进行计算,避免浮点到整数的转换和舍入错误。就连我也陷入了困境!