2009-09-14 12 views

Odpowiedz

15

Zobacz Math::BigInt

use Math::BigInt; 
$x = Math::BigInt->new("3"); 
print $x ** 333; 

wyjściowa:

760988023132059809720425867265032780727896356372077865117010037035791631439306199613044145649378522557935351570949952010001833769302566531786879537190794573523 
+0

Ace. Dokładnie to, czego potrzebowałem. –

2

Z liczb że duży może masz więcej cyfr niż precyzją używane do przechowywania numerów. (Zrozumienie prostego, działającego przykładu rozwiązałoby to pytanie).

Jeśli naprawdę potrzebujesz zobaczyć wszystkie 150 cyfr, powinieneś użyć biginta (dla liczb całkowitych), bigrat (dla liczb wymiernych) i binarnych (dla liczb zmiennoprzecinkowych).

6

Jeśli chcesz to zrobić dla wszystkich liczb całkowitych w programie, można tylko dodać:

use bigint; 

Jeśli tylko chcesz to zrobić dla pewnych liczb całkowitych, można utworzyć Math::BigInt obiektów.

Istnieje również bignum i Math::BigNum, jeśli pracujesz z pływakami.

3

Dla bardzo małych wartości patrz poniższy kod:

my $value = 1e-07;     # = 0.0000001 

# NOPE 

print $value;      # prints 1e-07, $value is a number 
print sprintf("%f", $value);  # prints 0, $value is a number 
print sprintf("%.10f", $value); # prints 0.0000001000, $value is a number 
$value = sprintf("%.10f", $value); 
print $value      # prints 1e-07, $value is a number 

# /NOPE 

use bignum; 
$value = ($value+0)->bstr(); 
print $value;      # prints 0.0000001, $value is a string 
no bignum; 
print $value;      # prints 0.0000001, $value is a string 

# HOORAY 
0

miał ten sam problem z tym kodem:

#!/usr/bin/perl 
use strict; 
use warnings; 
print "Base Exp MAX Signed-Negitive  MAX Signed-Positive   MAX Unsigned\n"; 
for(my $x = 1; $x <= 64; $x++) { 
    my $y = (2 ** $x); 
    printf("2^%4d = %20d to %-20d or %20d\n", 
       $x, $y/-2, $y/2, $y); 
} 

Ostatnie dwa wiersze gdzie druk:

2^ 63 = -4611686018427387904 to 4611686018427387904 or -9223372036854775808 
2^ 64 = -9223372036854775808 to -9223372036854775808 or     -1 

Oczywiście nie, i nie zdając sobie sprawy, że przyczyną problemu była konwersja% d, wypróbowałem rozwiązanie oznaczone tutaj:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Math::BigInt; 
print "Base Exp MAX Signed-Negitive  MAX Signed-Positive   MAX Unsigned\n"; 
for(my $x = Math::BigInt->new('1'); $x <= 64; $x++) { 
    my $y = Math::BigInt->new(2 ** $x); 
    printf("2^%4d = %20d to %-20d or %20d\n", 
       $x, $y/-2, $y/2, $y); 
} 

Wtedy zdałem sobie sprawę, że konwersja printf "d" spowodowała problem. Czytania na Math :: BigInt wydaje się sugerować, że te numery są przechowywane jako ciągi wewnątrz, więc zmiana do nawrócenia „S”, stała się kwestią:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Math::BigInt; 
print "Base Exp MAX Signed-Negitive  MAX Signed-Positive   MAX Unsigned\n"; 
for(my $x = Math::BigInt->new('1'); $x <= 64; $x++) { 
    my $y = Math::BigInt->new(2 ** $x); 
    printf("2^%4s = %20s to %-20s or %20s\n", 
       $x, $y/-2, $y/2, $y); 
} 

Teraz dwie ostatnie linie wydrukowane prawidłowo:

2^ 63 = -4611686018427387904 to 4611686018427387904 or 9223372036854775808 
2^ 64 = -9223372036854775808 to 9223372036854775808 or 18446744073709551616 

Ale w odniesieniu do odpowiedzi Karela, która była prawie poprawna IMHO, można to zrobić bez użycia BigInt (bigint, BigNum, ...) Za pomocą „f” konwersję ale z precyzją ustawiony na „0”, aby wyeliminować te dziesiętne:

#!/usr/bin/perl 
use strict; 
use warnings; 
print "Base Exp MAX Signed-Negitive  MAX Signed-Positive   MAX Unsigned\n"; 
for(my $x = 1; $x <= 64; $x++) { 
    my $y = (2 ** $x); 
    printf("2^%4d = %20.0f to %-20.0f or %20.0f\n", 
       $x, $y/-2, $y/2, $y); 
} 

ta działa również na pytanie PO za:

perl -e 'printf "%.0f\n", 3 ** 333' 
760988023132059813486251563646478824265752535077884574263917414498578085812167738721447369281049109603746001743233145041176969930222526036520619613114171654144 
+0

Używanie 'printf"% .0f \ n "' do drukowania dużych intów jest * naprawdę * złym pomysłem. Zauważ, że dane wyjściowe, które otrzymasz na ostatnim wydruku, zgadzają się z wynikiem przyjętej odpowiedzi tylko w pierwszych 16 cyfrach. Jeśli ktoś wyrzuci tak dużo precyzji, równie dobrze może pracować z pływakami. – kjo