0

我正在为一个班级创建一种收银机程序,它需要一个购买金额和一个投标金额,然后给出剩余金额,然后将其分成每张账单的数量。问题是当我尝试存储浮点数时,它不会将数字存储在点的右侧。

这是我的代码:

int main(void)
{
    float purchase_amount = 0.00f,
        amount_tendered = 0.00f,
        calculated_return = 0.00f;
    float *p_return_amount;

    printf("Welcome to Change Counter!\n\n");

    printf("Please enter the total amount of purchase: ");
    scanf("%f", &purchase_amount);

    printf("\nPlease enter amount of money tendered: ");
    scanf("%f", &amount_tendered);

    // Debug output
    printf("\n\nPurchase Amount: %.2f\nAmount Tendered: %.2f ", purchase_amount, amount_tendered);

    calculated_return = amount_tendered - purchase_amount;
    p_return_amount = &calculated_return;

    printf("\n\nYour change is: %.2f", *p_return_amount);

    system("pause");
    return EXIT_SUCCESSFUL;
}

它只发生在非常大的数字上,而这正是我正在使用的。说 14990300.54 和 15000000.21 只存储 14990301.00 和 15000000.00。我出于某种原因自动四舍五入。

我的语法有问题吗?浮点数是否太小?

谢谢。

4

3 回答 3

4

类型的大小和精度float可能因系统而异,但通常是 32 位,只有大约 7 个十进制数字,这与您所看到的一致。

更改为类型double(通常为 64 位和大约 11 个十进制数字)对于您正在做的事情可能已经足够了。

但请记住,浮点实际上以二进制而不是十进制存储值。例如,该值0.01不能完全存储为二进制分数,1.0/3.0也不能完全存储为十进制。

在现实生活中,您可能不想使用浮点数进行涉及金钱的计算。一个好的选择是将所有金额存储为代表美分数量的整数(或任何您需要处理的最小金额),并根据输入和输出的需要进行缩放。例如,一个 32 位有符号整数类型可以存储高达约 2100 万美元的金额;64 位有符号整数可以存储比您需要担心的更多的钱(只要您不处理津巴布韦元)。

一个简单的例子:假设你有一个long int代表 $123.45 的值12345。您可以将其打印为:

printf("%ld.%02d\n", value/100, value%100);

这并不总是足够好。例如,如果你在计算利息,加上 10% 的利息123.45给你135.795,这不是美分的整数。我了解有法律明确规定银行和其他金融机构必须如何进行此类计算。我个人几乎不知道这些法律到底说了些什么——对于你现在正在做的事情,你可能也不需要这样做。

另一方面,浮点数可能足以满足您当前的目的,即使由于舍入误差您可能会在这里和那里获得或损失一分钱。问问你的导师,并记住,这对于现实世界的货币计算来说是不够的,至少在没有特别小心的情况下是这样。

我建议将 Goldberg 的“每个计算机科学家都应该知道的关于浮点运算的知识”添加到您有一天要阅读的内容列表中。对于您现在正在做的事情而言,它可能过于详细,但值得您记住。

于 2013-01-05T22:15:22.943 回答
2

float仅存储 7 个有效数字。如果您想要更高的精度,请double改用。double可存储 16 位有效数字。

有关浮点数的更多详细信息,另请参阅IEEE 浮点

于 2013-01-05T22:13:04.123 回答
-1

是的,浮点值在设计上是不精确的,afloat将给出大约 6 个小数位。

永远不要对货币使用浮点值。使用具有适当舍入规则的整数。(即以整便士/美分计算,并确保在划分数量时保留总和。)

于 2013-01-05T22:12:32.400 回答