这段代码有一个bug

时间:2017-10-02 18:52:38

标签: c debugging onlinejudge

我是this online judge中的初学者问题解决者。前20个问题我做得很好。但是没有。 21我卡住了。我写了这段代码:

#include <stdio.h>
#include <math.h>
int main()
{
    double notes[] = {100, 50, 20, 10, 5, 2};
    double moedas[] = {1, 0.50, 0.25, 0.10, 0.05, 0.01};
    int amount_of_notes[6];
    int amount_of_moedas[6];
    double n, x;
    int i, j;
    scanf("%lf", &n);
    printf("NOTAS: \n");
    for(i = 0; i < 6; i++)
    {
        x = fmod(n, notes[i]);
        amount_of_notes[i] = n/notes[i];
        n = x;
        printf("%d nota(s) de R$ %.2lf\n", amount_of_notes[i], notes[i]);
    }
    printf("MOEDAS: \n");
    for(j = 0; j < 6; j++)
    {
        amount_of_moedas[j] = n/moedas[j];
        x = fmod(n, moedas[j]);
        n = x;
        printf("%d moeda(s) de R$ %.2lf\n", amount_of_moedas[j], moedas[j]);
    }
    return 0;
}

此代码在C中。此代码将数字转换为某些钞票&amp;硬币。但是当我输入54.54时输出如下:

NOTAS: 
0 nota(s) de R$ 100.00
1 nota(s) de R$ 50.00
0 nota(s) de R$ 20.00
0 nota(s) de R$ 10.00
0 nota(s) de R$ 5.00
2 nota(s) de R$ 2.00
MOEDAS: 
0 moeda(s) de R$ 1.00
1 moeda(s) de R$ 0.50
0 moeda(s) de R$ 0.25
0 moeda(s) de R$ 0.10
0 moeda(s) de R$ 0.05
3 moeda(s) de R$ 0.01

正如您所看到的那样,在最后一行只有3显示了应该显示4的位置。我努力在代码中找到错误。我失败了。请帮忙找到这段代码的错误!!

2 个答案:

答案 0 :(得分:1)

避免任何需要精确的浮点变量。浮动不精确,您将面临舍入错误。在你的情况下,你期望4,但由于舍入错误而得到3。

而是使用整数进行所有计算,并使用美分作为基本单位。

类似的东西:

#include <stdio.h>
#include <math.h>
int main()
{
    int notes[] = {10000, 5000, 2000, 1000, 500, 200}; // Unit is cents
    int moedas[] = {100, 50, 25, 10, 5, 1};            // Unit is cents
    int amount_of_notes[6];
    int amount_of_moedas[6];
    double n;
    int x;
    int n_int;
    int i, j;
    scanf("%lf", &n);
    n_int = 100 * n;                                  // Unit is cents
    printf("NOTAS: \n");
    for(i = 0; i < 6; i++)
    {
        x = n_int / notes[i];
        amount_of_notes[i] = x;
        n_int -= x * notes[i];
        printf("%d nota(s) de R$ %.2lf\n", amount_of_notes[i], notes[i]/100.0);
    }
    printf("MOEDAS: \n");
    for(j = 0; j < 6; j++)
    {
        x = n_int / moedas[j];
        amount_of_moedas[j] = x;
        n_int -= x * moedas[j];
        printf("%d moeda(s) de R$ %.2lf\n", amount_of_moedas[j], moedas[j]/100.0);
    }
    return 0;
}

输入:

54.54

输出:

NOTAS: 
0 nota(s) de R$ 100.00
1 nota(s) de R$ 50.00
0 nota(s) de R$ 20.00
0 nota(s) de R$ 10.00
0 nota(s) de R$ 5.00
2 nota(s) de R$ 2.00
MOEDAS: 
0 moeda(s) de R$ 1.00
1 moeda(s) de R$ 0.50
0 moeda(s) de R$ 0.25
0 moeda(s) de R$ 0.10
0 moeda(s) de R$ 0.05
4 moeda(s) de R$ 0.01

答案 1 :(得分:1)

该错误与计算机处理浮点数的方式有关。该资源对该主题有很好的解释。

http://floating-point-gui.de/

有几种方法可以解决这个问题,在你的情况下我认为使用整数是最好的选择。您可以将“notes”和“moedas”值作为整数(将它们全部乘以100)开始,并对输入执行相同操作。这不会改变最终结果,但你会处理整数而不是浮点数。并且由于整数是精确的(没有舍入误差),结果将是您所期望的。

这里有基于您的代码的概念证明。请注意,我只做了最小的改动才能使其发挥作用,还有很大的改进空间。

https://repl.it/Lxg0/2