C中带有浮点数的现金分配错误
cash division error in C with floating points
我目前正在研究 cs50 "cash" 问题:估算支付零钱所需的硬币数量。
例如:欠 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;
}
剩下的应该很简单;)
在您的 C 实现中,这些行:
float dime = 0.10;
float nickel = 0.05;
float penny = 0.010000;
将 dime
设置为 0.100000001490116119384765625,将 nickel
设置为 0.0500000007450580596923828125,将 penny
设置为 0.00999999977648258209228515625。这导致每个硬币的计算略有偏差。此外,change
在处理每个硬币后的计算存在舍入误差。
要解决此问题,在使用 get_float
获得 change
后,使用以下方法将其转换为美分数:
int cents = roundf(change * 100);
然后用整数运算执行所有计算。 (包含 <math.h>
以获得 roundf
的声明。)
只是一个建议,为什么不用整数运算来执行所有的计算?将浮点数"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
我也恭敬地建议使用非常相似的变量名称,例如quarter和quarters,很可能会导致错误。
由于您永远不想更改一个季度的美分数(尤其是意外),您可以将其声明为 const int。
您可能还想检查用户是否输入了他们认为是美元的小数(浮点数)金额,而不是整数美分。但这超出了这个问题的范围。
我目前正在研究 cs50 "cash" 问题:估算支付零钱所需的硬币数量。
例如:欠 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;
}
剩下的应该很简单;)
在您的 C 实现中,这些行:
float dime = 0.10;
float nickel = 0.05;
float penny = 0.010000;
将 dime
设置为 0.100000001490116119384765625,将 nickel
设置为 0.0500000007450580596923828125,将 penny
设置为 0.00999999977648258209228515625。这导致每个硬币的计算略有偏差。此外,change
在处理每个硬币后的计算存在舍入误差。
要解决此问题,在使用 get_float
获得 change
后,使用以下方法将其转换为美分数:
int cents = roundf(change * 100);
然后用整数运算执行所有计算。 (包含 <math.h>
以获得 roundf
的声明。)
只是一个建议,为什么不用整数运算来执行所有的计算?将浮点数"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
我也恭敬地建议使用非常相似的变量名称,例如quarter和quarters,很可能会导致错误。
由于您永远不想更改一个季度的美分数(尤其是意外),您可以将其声明为 const int。
您可能还想检查用户是否输入了他们认为是美元的小数(浮点数)金额,而不是整数美分。但这超出了这个问题的范围。