我不确定为什么我的代码产生这个算术错误?

时间:2016-03-16 19:51:46

标签: c floating-point cs50

嘿,我正在研究c中的一个程序,告诉你任何给定金额所需的硬币数量最少。我有一个程序编写,适用于我测试的每个金额,除了$ 4.20。

这是我的代码:

#include <cs50.h>
#include <stdio.h>
#include <math.h>

int main(void)
{
    float f;
    int n, x, y, z, q, s, d, t;

    do {
        printf("How much change do you need?\n");
        f = GetFloat();
    } while(f <= 0);

    {
        n = (f * 100);
    }

    q = (n / 25);
    x = (n % 25);
    y = (x / 10);
    z = (x % 10);
    s = (z / 5);
    d = (z % 5);
    t = (q + y + s + d);

    {
        printf("%d\n" ,t);
    }
}

奇怪的是当我输入4.20时,输出是22而不是18(16个季度和2个角钱)。我做了一些调查,发现问题出在我的变量x上。当我输入4.2时,x给我19而不是20。我尝试了其他我认为应该产生相同问题的案例,如5.2和1.2,但它在这些情况下正常工作。这可能是一个舍入问题,但我认为同样的错误也会发生在那些相似的值上。

有没有人知道为什么会这样?

PS我对编码很新,我没有得到太多正式的指导,所以如果你看到任何明显的东西,我也欢迎提供更好的缩进和格式化的提示。

2 个答案:

答案 0 :(得分:3)

IEEE 754 floating point通常略显不精确,而且施法会截断,而不是圆形。可能发生的是4.20 * 100评估为419.999999999999994(确切数字不重要,重点是,它不是420),转换为int会降低小数部分,产生419。

简单的方法就是:

n = f * 100 + 0.5;

或者您可以使用正确的功能:

n = round(f * 100);

如果数字是&#34;几乎&#34;确切地说,任何一个都没问题,只有当有人通过非整数分("4.195"之类)时才会出现差异,并且如果您使用float作为货币值,你已经接受了边际的精度问题;如果您需要精确数字,则可以使用具有固定精度的decimal格式作为小数值,并用于财务计算。

答案 1 :(得分:-2)

试试这个:提供最多2位数的精确度。

//float f
double f

f *= 1000;
f = floor(f);  /* optional */
f /= 10;
f = floor(f);  /* optional */
n = f;