9

为什么这个 C 程序给出“错误”的输出?

#include<stdio.h>

void main()
{
    float f = 12345.054321;

    printf("%f", f);

    getch();
}

输出:

12345.054688

但输出应该是,12345.054321

我在 VS2008 中使用 VC++。

4

5 回答 5

11

它给出了“错误”的答案,仅仅是因为并非所有真实值都可以用浮点数(或双精度数)来表示。您将得到的是基于底层编码的近似值。

为了表示每个实际值,即使在 1.0x10 -100和 1.1x10 -100之间(一个真正的微小范围),您仍然需要无限数量的位。

单精度 IEEE754 值只有 32 位可用(其中一些用于其他任务,例如指数和 NaN/Inf 表示),因此无法为您提供无限精度。它们实际上有 23 位可用,精度约为 2 24(还有一个额外的隐式位)或超过 7 个十进制数字(log 10 (2 24 ) 大约为 7.2)。

我用引号将“错误”一词括起来,因为它实际上并没有错。问题在于你对计算机如何表示数字的理解(不过不要被冒犯,你并不孤单)。

前往http://www.h-schmidt.net/FloatApplet/IEEE754.html并在“十进制表示”框中输入您的号码以查看此操作。

如果您想要一个更准确的数字,请使用双精度而不是浮点数 - 它们具有双倍可用于表示值的位数(假设您的 C 实现分别使用 IEEE754 单精度和双精度数据类型来表示浮点数和双精度数)。

如果您想要任意精度,您将需要使用像GMP这样的“bignum”库,尽管它比原生类型要慢一些,因此请确保您了解权衡取舍。

于 2010-05-11T06:29:15.733 回答
2

float十进制数 12345.054321在您的平台上无法准确表示为 a 。您看到的结果是可以表示为的最接近数字的十进制近似值float

于 2010-05-11T06:28:43.410 回答
2

floats 是关于方便和速度,并使用二进制表示 - 如果您关心精度,请使用十进制类型。

要理解这个问题,请阅读每个计算机科学家应该知道的关于浮点运算的知识:http : //docs.sun.com/source/806-3568/ncg_goldberg.html

有关解决方案,请参阅十进制算术常见问题解答http ://speleotrove.com/decimal/decifaq.html

于 2010-05-11T06:32:41.827 回答
1

这一切都与精度有关。您的号码无法准确存储在浮点数中。

于 2010-05-11T06:30:46.517 回答
0

单精度浮点值只能表示大约八到九个有效(十进制)数字。超过这一点,您会看到量化误差。

于 2010-05-11T06:30:26.057 回答