微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C怎么能打印一个超大号码?

这个代码如何打印这么大的数字? 我已经在Ubuntu 14.04(gcc 4.8.2)上试过了。 它在任何编译器(甚至MinGW,称为“gcc for Windows”)的MS Windows上都不起作用。 为什么?

#include <stdio.h> #include <math.h> int main() { printf("%.0fn",pow(2,500)); }

Ubuntu输出

3273390607896141870013189696827599152216642046043064789483291368096133796404 674554883270092325904157150886684127560071009217256545885393053328527589376

Windows输出

3273390607896141900000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000

(为了清晰起见,添加换行符。)

编译一个有限的库访问的程序

编译生成机器上的Java代码给出major.minor错误52

共享Apache 2.0模块vs静态Apache模块

如何在Windows上编译和运行xv6?

g ++ -D标志是做什么的?

在Ubuntu 10.10 x86_64上编译GLIBC-2.13

什么是Mcrt1.o和Scrt1.o的用法

从sictus prolog pl文件窗口创build一个独立的exe文件

在Windows 8.1的铿锵cl奇怪的编译错误

Linux – 你能编译和运行一个terminal线程序吗?

正如OP所暗示的和@ user300234的评论, 2^500是一个501位的数字,但这不是问题。

pow(2,500)返回一个double ,约为3.27e150 ,这通常是一个二进制64 。 这种类型支持大约15 – 17位精度的十进制数字。 所以对于3.27e150 附近的数字3.27e150 ,多打印17位数字通常并不重要。 它比DBL_MAX ,可能是1.798e308 。

这里的诀窍是pow(2,500) 完全可以表示为浮点数double (binary64)。 这可能会产生一个错觉,即double精度有几百位的精度 – 事实并非如此。

这两个不同的编译处理以不同的方式将double精度转换为文本,一旦打印了17位左右的数字,这是C规范允许的。 正确数字的最小数量是DBL_DECIMAL_DIG – 在两个系统上可能是17。

考虑打印下一个更大的double 。 虽然下一个double可以打印150个左右的数字,但通常这些额外的数字通路DBL_DECIMAL_DIG对于许多应用程序来说只是噪声。

// 2 ^ 500 327339060789614 187001318969682759915221664... // next 327339060789614 259685191399243448970154045...

MinGW也使用的Microsoft Visual C运行时库( msvcrt.dll )仅支持17位精度,因为这足以唯一地标识(IEEE 754) double 。

但好消息是,使用VS2015 CTP4编译的代码与Ubuntu示例产生的输出相同。 如果你使用的是MinGW-w64,你可以在包含<stdio.h>之前将__USE_MINGW_ANSI_STdio定义为1 ,或者通过-D编译器选项来定义相同的输出

这不是一个新的答案,而是与其他人已经说过的略有不同:

差异不在pow()函数中:不同之处在于printf()函数。 Ubuntu printf()打印pow(2,500)的确切十进制值pow(2,500) 。 Windows printf()正在打印一个近似17位十进制数的正确值。

在某种意义上,这两种实现都是正确的; 但我会说Windows的printf() 更正确。 原因如下:

如果你关心超过17位的精度,那么你不应该使用double精度。

一般来说, 大多数双重计算的结果在前17个数字中是正确的。 ( pow(2,n)是一个非常特殊的情况,对于范围内的任何n ,答案都是完全正确的。)通过输出非常大的双精确的十进制值,Ubuntu库正在愚弄你; 假设你有

double a = ...; double b = ...; double c = a*b; printf("%f",c);

您不想知道c的确切值,因为对于大多数a和b , c 不等于 a*b :它只是a *的近似值 – 一个精确到17位有效数字的近似值。

如果你需要17位以上的精度,那么你应该使用像GMP( https://gmplib.org/ )这样的扩展精度的数学库,

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐