How can I printf a Perl bignum without losing prec

2019-04-12 04:13发布

#!/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条回答
等我变得足够好
2楼-- · 2019-04-12 04:51

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.

查看更多
登录 后发表回答