2016-10-08 7 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; 

によって定義され、

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

だから、あなたの数は長いに収まらない場合には(少なくとも私のPerlの上に、私は、これは設定可能だと思います) (%d)または符号なしlong(%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はそれらを処理することを期待する理由はありません。代わりに、as_hexbnstrなどのライブラリのconversion functionsを使用できます。数字だけを印刷する場合は、print "$value\n";を使用してください。

+4

bigintプラグマは、コアPerl 5に含まれているので、なぜPerl 5が正しく処理すると思うのでしょうか(余分なドキュメントはありません)。 –

関連する問題