Reputation: 37146
I just spent an epoch figuring out that my big integer was fine and that printf
's %d
/%u
were not up to the task of displaying it:
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
I wouldn't be surprised if the answer is no, just wanted to confirm it.
Upvotes: 3
Views: 1366
Reputation: 118148
Given that you have to use a specific library for the purpose of manipulating such numbers, there is no reason to expect that the builtin printf
would handle them. Instead, you can use the library's conversion functions such as as_hex
or bnstr
. If you just want to print the number, use print "$value\n";
.
Upvotes: 4
Reputation: 386331
Yes. %s
is the only format for strings.
%%
: Obviously no.%c
: Obviously no.%s
: Yes.%d
: Only if the number fits in a signed integer.%u
, %o
, %x
, %X
, %b
, %B
: Only if the number fits in a unsigned integer.%e
, %E
, %f
, %g
, %G
, %a
, %A
: Only if the number fits in a floating point number.%p
: Obviously no.%n
: Obviously no.Upvotes: 4
Reputation: 64919
This was surprisingly hard to track down. I didn't see anything obvious in the docs, so I went to the source. The printf
function is implemented (at the bottom of a long call stack) by the C function Perl_sv_vcatpvfn_flags
. It appears as if this function assumes the number will fit in an IV or a UV. They are defined by
typedef IVTYPE IV;
typedef UVTYPE UV;
Which is in turn defined by (at least on my Perl, I think this is configurable)
#define IVTYPE long /**/
#define UVTYPE unsigned long /**/
So, if your number won't fit in a long, then (%d
) or in an unsigned long (%u
), then a string (%s
) is your only option. A bigger quesiton is why you are using printf
in the first place. Are you formatting these numbers in some way other than printing them? If not, then print
should just do the right thing.
Upvotes: 11