Как я могу печатать Perl Bignum без потери точности? - PullRequest
3 голосов
/ 25 марта 2011
#!/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; 
}   

Мой Perf printf (ActiveState v5.10.1, созданный для darwin-thread-multi-2level), использующий преобразование% f, не учитывает мое значение после цифры 1e-6, даже при использовании bignum:

$ t.pl
bignum==0
         1234567890.123456789
         1234567890.123456717

bignum==1
         1234567890.123456789
         1234567890.123456717

Как я могу напечатать свой ввод без потери точности?

Моя реальная проблема в том, что мне нужно будет манипулировать этим числом (например, $ x / 0.000_000_001 или, что еще хуже, $ x / 0.000_001_024, с которым я не могу подделать вызовы функции substr ()), но текущее снижение уже поставило меня в тупик, прежде чем я смогу перейти к «веселой» части.

1 Ответ

9 голосов
/ 25 марта 2011

Perl's printf на самом деле не делает бигнумов. Используйте один из методов Math :: BigFloat для получения строки. Так как занимаюсь

my $x = $s;

просто копирует строку, вам придется сделать что-то вроде

my $x = 0+$s; 

так что $x является Math :: BigFloat. Тогда что-то вроде

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

должен делать то, что вы хотите.

...