C 语言舍入错误 - 硬件?软件我?[复制]

C language rounding error - Hardware? Software Me? [duplicate]

提问人:Jim 提问时间:1/6/2023 更新时间:1/6/2023 访问量:70

问:

首先,我的环境:

经销商 ID:Bunsenlabs 描述: BunsenLabs GNU/Linux 10.5 (Lithium) 版本:10.5 代号:buster

线程模型:posix gcc 版本 8.3.0 (Debian 8.3.0-6)

我在使用旧的 C 程序时遇到了程序中的舍入错误。我已将代码复制到下面的程序“example.c”中:

main()
{
    float acntBalance;
    int dollars;
    int cents;
    float fcents;
    
    dollars = 303466;
    cents = 95; 
    fcents = cents * 0.01;
    acntBalance = dollars + fcents;
    printf("Dollars(%d) + Cents(%f) = %f \n",dollars,fcents,acntBalance);
}

并使用 GNU 编译器编译此代码,如下所示:

gcc -w -g -o 示例 example.c

将 303466 美元加到 95 美分应该是 303466.95, 但打印为 303466.937500。

这是一个会计程序,1美分的折扣是不可接受的。

这对我来说看起来像一个错误,但是我已经很久没有开发 C 程序了,所以我会说“用户错误”是这里最相似的问题。但这似乎很基本,以至于我看不出我在哪里犯了错误。

如果错误不是我的,是 H/W 还是 S/W。我已经在 2 台不同的主机上运行了该程序,因此它使我相信这是一个 S/W 错误。但是在哪里呢?

任何人都可以在我的代码中看到错误吗?

c 精度

评论

1赞 Robert Harvey 1/6/2023
这很可能是浮点数工作方式的结果。该类型只会为您提供大约 7 位精度float
1赞 Retired Ninja 1/6/2023
浮点数学坏了吗?值得一读。切勿使用浮点值进行货币计算。为什么不使用 Double 或 Float 来表示货币?
3赞 Robert Harvey 1/6/2023
你如何解决它?将所有内容存储为整数类型的美分,进行整数算术运算,然后在显示结果时将结果正确格式化为美元和美分。
0赞 Steve Summit 1/6/2023
这永远不会使用 type .至少,(a) 将 type 用于 .然后,(b)在末尾打印它。floatdoubleacntBalance%.2f
0赞 Steve Summit 1/6/2023
数字 303466.95 在单精度浮点数中不存在。最接近的是 303466.93 或 303466.94(如您所见,实际上是 303466.9375)。这个数字也不存在双精度,但至少在那里,你可以得到一个像 303466.95000000001 这样的数字,只要你在打印时使用四舍五入不需要的 0.000000000001,它就足够接近了。%.2f

答:

0赞 Jonatan Porras 1/6/2023 #1

%.1f = 小数点后一位 %.2f = 小数点后两位 ...

printf(“美元(%d) + 美分(%f) = %.2f \n”,美元,美分,acntBalance);

评论

0赞 alter_igel 1/6/2023
在这种情况下,这将打印 94 美分,而不是 95 美分。真正的问题是这是不准确的,但 OP 想要确切的金额。float