How can I printf a Perl bignum without losing precision?

落爺英雄遲暮 提交于 2020-01-01 16:28:47

问题


#!/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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!