3

我创建了一个类似 ATM 的程序,将钱存放在一个人的帐户中。当此人提款时,它会从账户中扣除提款以及 0.50 的附加费。我遇到的问题是在这个程序中同时使用整数和浮点数。我将整数帐户转换为浮点数,但在尝试打印语句时收到错误消息。有人可以告诉我我做错了什么吗?

#include <stdio.h>

int main (void) {
    int account = 2000;
    int withdrawal;
    float charge = 0.50;

    printf ("How much money would you like to take out? ");
    scanf ("%i", &withdrawal);

    while (withdrawal % 5 != 0) {
        printf ("Withdrawal must be divisible by 5. ");
        scanf("%i", &withdrawal);
    }

    account = ((float) account - charge) - withdrawal;

    printf("Remaining account: %.2f\n", account);

    return 0;
}
4

7 回答 7

7
int account = 2000;
printf("Remaining account: %.2f\n", account);

这是错误的;它应该是"%d"整数,或者更好,将您的account变量类型更改为可以代表您额外收费的 0.50 的东西。我也不建议您使用(不精确的)floats 来赚钱。10.499999997当你的意思时,你不想退出10.5。您需要考虑使用的精度和舍入规则。AFAIK 这些都是法律或其他规定的。

于 2012-01-16T21:22:07.240 回答
5

您根本不能使用浮点值来表示货币,因为它们具有错误的属性。并非所有数字都可以精确表示,因此您会产生“神秘”的效果。

最好使用“定点”方法,最简单的方法是采用较大的整数类型,例如long,然后将其乘以一个整数,如果您需要的只是整美分(对于美国货币),通常为 100。如果您需要美分的分数,请乘以更多,例如 10,000,以便能够表示低至 1/100:一美分的所有值。

使用此方案,1 美元将是:

long one_dollar = 1 * 10000;

13 美分将是:

long thirteen_cents = 13 * 100;

请注意,这反过来又限制了您可以代表的金额。最终,您可能会发现您需要一个任意精度的库来获得“无限”精度的整数。

于 2012-01-16T21:21:36.563 回答
3

不要在处理金钱时使用花车。使用整数类型来跟踪美分,然后在输出时将其转换为美元和美分(或任何货币)。

特别是,十进制0.1没有精确的浮点表示。相反,它表示为无限重复的二进制分数(0.19999999999.... hex)。同样,十进制0.01大约是 0.028F5C28F...十六进制

于 2012-01-16T21:21:40.173 回答
1

您看到的警告是由于您将 an 传递int给已将printf()%.2f作为格式字符串提供的事实。此格式字符串用于浮点数。见printf

然而,代码中有一个更根本的缺陷。当需要精确的小数时,不应使用浮点变量来表示数字,尤其是在处理货币金额时。简而言之,在您的应用程序中不使用浮点数的原因是小数不能精确表示。在每个位置数字系统中,一些数字由无限重复的序列表示。例如,

在十进制系统中,1/3 表示为 0.33[3]

(方括号表示无限重复的数字序列)。类似地,在二进制中,一些数字需要无限的 0 和 1 序列来表示。例如,

在二进制系统中,1/10 是 0.000110011[0011]

由于寄存器和内存位置的长度是有限的,因此向上或向下舍入并表示略高于或低于 0.1 的数字。因此,您不能将精确值 0.1 存储在 afloatdouble中。

有关更多详细信息,请参阅每位计算机科学家应了解的浮点运算知识

例如,一种替代方法是使用表示美分的整数变量。

于 2012-01-16T21:22:47.330 回答
1

让您的生活更轻松一点,而不是将您的“整数”视为美元,将它们视为“美分”,那么您将不需要浮点数。

于 2012-01-16T21:22:14.757 回答
0

在处理金钱时,您可能应该使用二进制编码的十进制。它将允许您对美元和美分使用单个变量。当您使用它时,您可以指定一个 typedef struct union,它可以让您指定以美元、美分、仅整美元和仅美分为单位的值。缺少与其他货币的兑换,这对几乎所有货币情况都有好处。

于 2012-01-16T23:19:22.007 回答
0

%2f即使它是一个整数,您也可以将account 打印为浮点数 ( ),您应该改用%d格式说明符

于 2012-01-16T21:22:59.933 回答