在计算 220 % 25 的余数为 20 而 420 % 25 的余数为 19 时计算余数的不一致? [复制]
Posted
技术标签:
【中文标题】在计算 220 % 25 的余数为 20 而 420 % 25 的余数为 19 时计算余数的不一致? [复制]【英文标题】:Inconsistencies when calculating the remainder where 220 % 25 gives a remainder of 20 while 420 % 25 gives a remainder of 19? [duplicate] 【发布时间】:2020-08-01 12:09:08 【问题描述】:作为 CS50 课程的一部分,我们的任务是创建一个程序(用 C 语言),根据用户提交的值计算最少的硬币数量(0.25 美元、0.10 美元、0.05 美元和 0.01 美元)。
我的想法是取输入值乘以 100 并使用整数,因为唯一感兴趣的值是硬币的数量而不是货币价值,因此我不必修改任何小数。
代码是:
#include <cs50.h>
#include <stdio.h>
#include <math.h>
int main(void)
//If it's NOT a positive number, do this.
float n;
do
n = get_float("Change owed: \n");
while (n <= 0);
//Multiplying change owed with 100 to avoid having to deal with decimals.
int cash = n * 100;
//Calculating the number of quarters ($0.25).
int quarters = cash / 25; //How many full quarters per cash.
int quarters_rem = cash % 25; //The remainder after full amout of quarters in cash.
printf("Number of quarters: %i\n", quarters); //Test how many quarters.
printf("Remainder: %i\n", quarters_rem); //Test how much remainder.
//Calculating the number of dimes ($0.10).
int dimes = quarters_rem / 10; //How many full dimes from the remainder when all quarters are deducted.
int dimes_rem = round(quarters_rem % 10); //The remainder after full amount of dimes in quarters_rem.
printf("Number of dimes: %i\n", dimes); //Test how many dimes.
printf("Remainder: %i\n", dimes_rem); //Test how much remainder.
//Calculating the number of nickels ($0.05).
int nickels = dimes_rem / 5; //How many full nickels from the remainder when all dimes are deducted.
int nickels_rem = round(dimes_rem % 5); //The remainder after full amount of nickels in dimes_rem.
printf("Number of nickels: %i\n", nickels); //Test how many nickels.
printf("Remainder: %i\n", nickels_rem); //Test how much remainder.
//Calculating the number of cents ($0.01).
int cents = nickels_rem; //How many full cents from the remainder when all nickels are deducted.
printf("Number of cents: %i\n", cents); //Test how many nickels.
//Prints the least number of coins to be returned.
int coins = quarters + dimes + nickels + cents;
printf("%i\n", coins);
问题是,当我运行代码并输入 2.2、6.2 或 8.2 时,在计算四分之一后,输出给我的余数是 20。 2.2 x 100 = 220 -> 25 x 8 = 200,如预期的那样,余数为 20。 2.2、6.2、8.2、10.2、12.2、14.2 等都是如此。
但是,如果我进入 4.2,这不是!真的!如果我输入 4.2 我期望: 4.2 x 100 = 420 -> 25 x 16 = 400 这应该给我 20 的余数,但我得到了 19 的余数?我不明白为什么在这种情况下余数是 19 而在其他情况下是 20?
【问题讨论】:
底线是:永远不要使用“普通”浮点类型来赚钱。有人会赔钱。 它应该解释一切:godbolt.org/z/Pq4Tjj @AdrianMole 有人会松,有人会赚钱。如果您是赢家,请使用花车:)int cash = n * 100;
截断乘积 - 不完全是 420。使用 long cash = lround(n * 100.0);
得到最近的一分钱而不是截断。
【参考方案1】:
浮点的典型实现以二进制格式存储数字,因此它不能精确存储一些十进制数字。
有了这个程序
#include <stdio.h>
int main(void)
float x = 4.2;
float y = x * 100;
printf("%.10f\n", y);
return 0;
I got output:
419.9999694824
这表明4.2f * 100
变得比420
略小,将其转换为int
将导致419
而不是420
。
为避免这种情况,在这种情况下,您应该在将float
转换为int
之前添加较小的值。
int cash = n * 100 + 0.1;
【讨论】:
以上是关于在计算 220 % 25 的余数为 20 而 420 % 25 的余数为 19 时计算余数的不一致? [复制]的主要内容,如果未能解决你的问题,请参考以下文章