2012-01-16 112 views
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; 
} 

回答

5

您完全不能使用浮点值来表示货币,因为它们具有错误的属性。并非所有的数字都可以完全代表,所以你会有“神秘”的影响。

最好使用“定点”方法,最简单的方法是取一个较大的整数类型,如long,然后乘以一个整数,通常为100,如果您只需要全部美分(对于美元)。如果您需要分数分数,请乘以比如10,000,以便能够将所有值降至1/100:1分。

有了这个计划,$ 1是:

long one_dollar = 1 * 10000; 

和13美分将是:

long thirteen_cents = 13 * 100; 

注意,这反过来又限制了如何大量的钱,你可以代表。最终,你可能会发现你需要一个任意精度库来获得“无限”精度整数。

+1

我希望通胀保持在足够低的水平,在我整个一生中,64位就足够了。 – 2012-01-16 21:27:04

3

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

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

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

这是错误的;它应该是整数或更好的"%d",将您的account变量类型更改为可能代表您正在充电的0.50的值。我不建议你使用(不精确的)float。当你的意思是10.5时,你不想撤回10.499999997。你需要考虑你要使用的精度和舍入规则。 AFAIK这些都是由法律或其他东西强制。

1

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

1

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

但是,代码中存在一个更基本的缺陷。当需要精确的小数部分时,您不应该使用浮点变量来表示数字,特别是在处理货币金额时。简而言之,在您的应用程序中不使用浮点数的原因是小数不能完全表示。在每个位置数字系统中,一些数字由无限重复序列表示。例如,在十进制1/3

被表示为0.33 [3]

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

二进制系统

,1/10是0.000110011 [0011]

由于寄存器和存储器位置是在长度有限的,这是或向下舍入和表示略微高于或低于一个数0.1。因此,您不能在floatdouble中存储0.1的确切值。

有关更多详细信息,请参见What Every Computer Scientist Should Know About Floating-Point Arithmetic

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

0

打印账户,如果它是一个浮点数(%2f),即使它是一个整数,你应该使用%d格式说明,而不是

0

与金钱打交道时,你应该使用二进制编码的十进制数。它将允许您为美元和美分使用单个变量。当你处理它时,你可以指定一个typedef结构体联合体,它允许你仅以美元,美分,全部美元和余数来指定值。与其他货币交换不足,这对几乎所有的货币情景都是有利的。