2011-03-24 3 views
2
#!/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; 
} 

printf de Perl Mon (ActiveState v5.10.1 construit pour darwin-fil multi-2level) en utilisant la conversion% f ne respecte pas ma valeur passée le chiffre 1E-6, même lorsque vous utilisez bignum:Comment puis-je imprimer un Perl bignum sans perdre de précision?

$ t.pl 
bignum==0 
     1234567890.123456789 
     1234567890.123456717 

bignum==1 
     1234567890.123456789 
     1234567890.123456717 

Comment puis-je imprimer mes données sans perte de précision?

Mon vrai problème est que je vais avoir besoin de manipuler ce nombre (par exemple, $ x/0.000_000_001, ou, pire, $ x/0.000_001_024, que je ne peux pas faux avec substr() appels de fonction), mais l'abattement actuel m'a bloqué avant que je puisse même arriver à la partie "amusante".

Répondre

9

Perl's printf ne fait pas vraiment bignums. Utilisez l'une des méthodes Math::BigFloat pour obtenir une chaîne. Depuis faisant

my $x = $s; 

que des copies de la chaîne, vous aurez à faire quelque chose comme

my $x = 0+$s; 

pour que $x est un Math :: BigFloat. Puis quelque chose comme

printf "%29s\n", $x->ffround(-9); 

devrait faire ce que vous voulez.

Questions connexes