c - 在计算 220 % 25 的余数为 20 而 420 % 25 的余数为 19 时计算余数的不一致?
问题描述
作为 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,则为 true!如果我输入 4.2 我期望: 4.2 x 100 = 420 -> 25 x 16 = 400 这应该给我 20 的余数,但我得到了 19 的余数?我不明白为什么在这种情况下余数是 19 而在其他情况下是 20?
解决方案
浮点的典型实现以二进制格式存储数字,因此它不能精确存储一些十进制数字。
有了这个程序
#include <stdio.h>
int main(void) {
float x = 4.2;
float y = x * 100;
printf("%.10f\n", y);
return 0;
}
419.9999694824
这表明4.2f * 100
变得略小于420
并将其转换为int
将导致419
而不是420
。
为避免这种情况,在这种情况下,您应该在转换float
为之前添加较小的值int
。
int cash = n * 100 + 0.1;
推荐阅读
- sqlite - 在有子句中使用 2 聚合
- c++ - 是否可以使用 new 运算符更改动态创建的数组的大小
- sql - 基于行级别的多列动态透视 Oracle 和 SQL Server
- c# - 将 datagridview 中的多条记录插入 SQL Server 数据库
- c# - Unity 中的 Mathf.Round 函数吐出奇怪的数字
- flutter - 如何调用Furute
在其他类中的功能...? - javascript - 在打字稿中使用这个关键字
- mysql - 使用 str_to_date() 将文本作为日期插入时出现“截断不正确的值”错误
- hash - 哈希表中出现主集群或辅集群怎么办
- sql - 从日期范围获取连续的月份和天数?