首页 > 解决方案 > 在计算 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?

标签: ccs50

解决方案


浮点的典型实现以二进制格式存储数字,因此它不能精确存储一些十进制数字。

有了这个程序

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

推荐阅读