2016-10-08 20 views
3

我只花了一个划时代搞清楚,我的大整数是个好人,是printf%d/%u都达不到显示它的任务:%s是唯一允许printf正确显示大整数的格式吗?

use strict; 
use warnings; 
use bigint; 
use List::Gen; 

*factorial = do {use bigint; <[..*] 1, 1..>->code}; 

my $value = factorial(32); 
printf "%d\n", $value; # -1 
printf "%u\n", $value; # 18446744073709551615 
printf "%s\n", $value; # 263130836933693530167218012160000000 

,我不会感到惊讶,如果答案是不,只是想确认一下。

回答

10

这是令人惊讶的难以追查。我没有在文档中看到任何明显的东西,所以我去了源头。函数printf由C函数Perl_sv_vcatpvfn_flags实现(在长调用堆栈的底部)。看起来好像这个函数假设这个数字会适合IV或UV。它们由

typedef IVTYPE IV; 
typedef UVTYPE UV; 

后者又由定义的定义(至少在我的Perl,我认为这是可配置)

#define IVTYPE   long   /**/ 
#define UVTYPE   unsigned long   /**/ 

所以,如果您的号码将不适合在一个长期的,然后(%d)或无符号长整型(%u),则字符串(%s)是您唯一的选择。更大的问题在于为什么你首先使用printf。你是否以某种方式格式化这些数字,而不是打印它们?如果没有,那么print应该做正确的事情。

+2

没有什么特别的理由使用'printf',除了当我开始喂食我的过程的巨大数字时它已经在那里了。 – Zaid

4

是的。 %s是唯一的字符串格式。


  • %%:显然没有。
  • %c:显然没有。
  • %s:是的。
  • %d:只有数字符合有符号整数。
  • %u%o%x%X%b%B:只有当数一个无符号整数适合。
  • %e%E%f%g%G%a%A:只有当数适合在一个浮点数。
  • %p:显然没有。
  • %n:显然没有。
4

既然你必须使用一个特定的库操纵这些数字的目的,没有理由期望,内置printf将处理它们。相反,您可以使用库的conversion functions,如as_hexbnstr。如果您只想打印该号码,请使用print "$value\n";

+4

bigint pragma是核心Perl 5的一部分,我可以看到为什么(没有额外的文档),您可能希望Perl 5能够正确处理它。 –