0

我正在使用带有 MinGW/GCC 4.7.1 的 Windows 7。我试图double ans = pow(2,1000)在 C 中执行。我发现ans无论我在改变数据类型方面做了什么尝试,都无法正确打印。

但是,我读到(实际上,在此页面的最底部),如果在 Linux 计算机上运行相同的东西,它会正确打印。

我知道我的 MinGW 文件夹中的 limits.h 文件中对 char、int 和 long long 施加的限制,但是 double 和 float 的限制在哪里?这些是否/可以从一个操作系统或架构到下一个有所不同?

编辑:

这是代码,它打印出截断的零填充答案:

#include <stdio.h>
#include <math.h>

int main(void)
{
   double ans = pow(2,1000);

   printf("%.0f", ans);

   return 0;
}
4

3 回答 3

6

您提出的问题与您所看到的问题无关。

您使用的所有系统很可能都使用相同的 type 表示double,即 64 位 IEEE 双精度。

pow(2, 1000)(或者,更等价和更清楚地,的值pow(2.0, 1000.0)是 2.0 1000。因为它是 2 的幂,所以可以精确表示——但是这么大的数字的相对精度非常粗糙。

一个double值通常只精确到大约 15 个十进制数字。

显然,在 Linux 系统上使用的 glibc 实现printf尝试打印该值的完整十进制表示,而其他printf实现将 15 位左右有效数字之后的部分或全部数字替换为零。后者可能更容易实现,但两种方法都有效。

在几个不同的系统上运行你的程序,我得到以下结果(为了便于阅读,折叠了行):

10715086071862673000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000

10715086071862673209484250490600018105614050000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000

10715086071862673209484250490600018105614048117055336074437503883703510511249361
22493198378815695858127594672917553146825187145285692314043598457757469857480393
45677748242309854210746050623711418779541821530464749835819412673987675591655439
46077062914571196477686542167660429831652624386837205668069376

最后一个恰好等于 2 1000

您要打印的数字是不寻常的,因为它非常大并且可以精确地表示——glibc 付出了一些额外的努力来精确地打印它。但更一般地说,浮点值往往不精确,很少值得担心前几位之外的任何数字。

例如,pow(2.0, 1000.0) + 1.0 不能精确表示,如果您尝试计算它,您可能会得到与pow(2.0, 1000.0).

于 2012-07-11T00:03:27.047 回答
3

的大小可能float因实现而异。double

保证double永远不会小于float,并且long double永远不会小于double- 类似于long long, long, int,的保证short

于 2012-07-10T23:07:44.873 回答
3

是的,float 和 double 等类型的实现可能因平台而异。

但是,最常见的现代平台使用浮点类型标准 IEEE 754。因此,除非您在不寻常的平台上,否则其中一种类型的二进制表示不太可能会有所不同。

您提到的另一个线程似乎强调了打印程序准确性的潜在差异。这并不意味着表示不同(或大小不同)。

于 2012-07-10T23:08:05.423 回答