问题
#!/usr/bin/perl
use strict;
use warnings;
my $s = "1234567890.123456789";
{
no bignum; printf "bignum==%s\n", bignum::in_effect() // 0;
my $x = $s;
printf "%29s\n", $x;
printf "%29.9f\n\n", $x;
}
{
use bignum; printf "bignum==%s\n", bignum::in_effect() // 0;
my $x = $s;
printf "%29s\n", $x;
printf "%29.9f\n\n", $x;
}
My Perl's printf (ActiveState v5.10.1 built for darwin-thread-multi-2level) using the %f conversion doesn't honor my value past the 1e-6 digit, even when using bignum:
$ t.pl
bignum==0
1234567890.123456789
1234567890.123456717
bignum==1
1234567890.123456789
1234567890.123456717
How can I print my input without losing precision?
My real problem is that I'm going to need to manipulate this number (e.g., $x/0.000_000_001, or, worse, $x/0.000_001_024, which I can't fake with substr() function calls), but the current abatement has stumped me before I can even get to the "fun" part.
回答1:
Perl's printf
doesn't really do bignums. Use one of the Math::BigFloat methods for getting a string. Since doing
my $x = $s;
just copies the string, you'll have to do something like
my $x = 0+$s;
so that $x
is a Math::BigFloat. Then something like
printf "%29s\n", $x->ffround(-9);
should do what you want.
来源:https://stackoverflow.com/questions/5426791/how-can-i-printf-a-perl-bignum-without-losing-precision