C 最低数量的硬币
请查找问题上下文,如下所示: 编写一个程序,接收表示金额的浮点值,例如表示2美元80美分的2.8。然后,程序应显示偿还硬币金额所需的最小硬币数量。假设用户输入的值大于0,小于10C 最低数量的硬币,c,floating-point,coin-change,C,Floating Point,Coin Change,请查找问题上下文,如下所示: 编写一个程序,接收表示金额的浮点值,例如表示2美元80美分的2.8。然后,程序应显示偿还硬币金额所需的最小硬币数量。假设用户输入的值大于0,小于10 #包括 内部主(空){ 双金额; printf(“输入金额:”); scanf(“%lf”、&amt); 国际货币单位; 金额=金额*100; 国际货币单位1; 1美元=每100美分的金额; 金额=金额-(美元1*100); 50美分; 美分=金额美分/50; 金额=金额-(分50*50); 20美分; 美分20=金额
#包括
内部主(空){
双金额;
printf(“输入金额:”);
scanf(“%lf”、&amt);
国际货币单位;
金额=金额*100;
国际货币单位1;
1美元=每100美分的金额;
金额=金额-(美元1*100);
50美分;
美分=金额美分/50;
金额=金额-(分50*50);
20美分;
美分20=金额美分/20;
金额=金额-(美分20*20);
国际货币基金组织10;
分10=金额分/10;
金额=金额-(分10*10);
国际货币基金组织05;
美分05=金额美分/5;
金额=金额-(美分05*5);
int cents_01;
美分=金额美分/1;
金额=金额-(美分01*1);
如果(1美元=0){
printf(“1美元的数量:%d\n”,1美元);
}
如果(美分50!=0){
printf(“50c的数量:%d\n”,美分/50);
}
如果(美分20!=0){
printf(“20c的数量:%d\n”,美分/20);
}
如果(分10!=0){
printf(“10c的数量:%d\n”,10美分);
}
如果(美分05!=0){
printf(“5c的数量:%d\n”,美分05);
}
如果(分_01!=0){
printf(“1c的数量:%d\n”,美分\u 01);
}
}
输出:
输入金额:1.1
1$:1的数量
10c数量:1
输入金额:2.1
1$:2的数量
10c数量:1
输入金额:3.1
1$:3的数量
10c数量:1
输入金额:4.1
1$:4的数量
5c数量:1
1c数量:4个
输入金额:5.1
1$:5的数量
5c数量:1
1c数量:4个
输入金额:6.1
1$:6的数量
10c数量:1
问题:
为什么4.1和5.1的值与0-10范围内的所有其他值的工作方式不同?
通过手动向下计算代码,似乎4.1和5.1应与所有其他情况一致,仅产生10c的值1,但执行程序时并非如此
为什么4.1和5.1的值与0-10范围内的所有其他值的工作方式不同
因为浮点数并不总是精确地表示值。请看以下代码:
double amt;
printf("Enter amount:");
scanf("%lf", &amt);
int amt_cents;
amt_cents = amt * 100;
如果在最后一行之后设置断点并检查amt\u cents
的值,您可能会发现它是409
而不是您期望的410
,因为amt
类似于4.09999999…
您需要将数字四舍五入到最接近的整数,而不是只取整数部分,一种简单的方法是将值加上0.5,然后截断:
amt_cents = amt * 100.0 + 0.5;
最接近4.1和5.1的双精度值稍微小一些,因此当作为整数舍入到409和509美分时。@mkrieger1:要想解决这个特定的程序,需要仔细筛选很多。如果你想要精确的美元和美分,尝试将美元金额和美分金额解析为单独的整数,而不是浮点值。这说明了为什么对货币使用浮点不是一个好主意<代码>金额=金额*100代码>-->
金额=lround(金额*100.0)代码>我认为金额*100
可以。由于amt
是double
,100
也应转换为double
。+0.5
部分是最重要的一部分。@Fredrarson我相信你是对的--100应该升级为双倍,而不是amt
降级为int。我的习惯是尽量避免混合类型,以避免类似的问题。我会编辑。有很多很好的舍入函数处理舍入比在+0.5
之后截断更好,后者在某些情况下失败。我推荐
amt_cents = amt * 100.0 + 0.5;