2009-09-14 13 views

risposta

15

Vedi Math::BigInt

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

uscita:

760988023132059809720425867265032780727896356372077865117010037035791631439306199613044145649378522557935351570949952010001833769302566531786879537190794573523 
+0

Ace. Proprio quello di cui avevo bisogno. –

2

Con i numeri che di grandi dimensioni si possono avere più cifre rispetto alla precisione utilizzato per memorizzare i numeri. (Vedere un semplice esempio eseguibile avrebbe risolto questa domanda).

Se è davvero necessario visualizzare tutte le 150+ cifre, è necessario utilizzare i moduli bigint (per i numeri interi), bigrat (per i numeri razionali) e bignum (per i numeri in virgola mobile).

6

Se si vuole farlo per tutti gli interi nel programma, si può semplicemente aggiungere:

use bigint; 

Se si desidera solo farlo per alcuni interi, è possibile creare oggetti Math::BigInt.

C'è anche bignum e Math::BigNum se si lavora con i galleggianti.

3

Per valori molto piccoli vedere il codice seguente:

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

avuto lo stesso problema con questo codice:

#!/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); 
} 

Le ultime due righe dove stampa:

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

Ovviamente non è giusto, e non rendendomi conto che la conversione% d stava causando il problema, ho provato la soluzione contrassegnata qui:

#!/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); 
} 

Ecco quando ho capito che la conversione di "d" di stampa stava causando un problema. Leggendo su Math :: bigint sembra suggerire che questi numeri sono memorizzati come stringhe all'interno, in modo da passare a una conversione 's', risolto il problema:

#!/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); 
} 

Ora le ultime due righe stampate correttamente:

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

Ma per quanto riguarda la risposta di Karel, che era quasi corretta IMHO, questo potrebbe anche essere fatto senza l'uso di BigInt (bigint, BigNum, ...) Utilizzando la conversione 'f', ma con la precisione impostato a '0' per eliminare quei decimali:

#!/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); 
} 

Questo funziona anche per la domanda del PO:

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

L'uso di 'printf"% .0f \ n "' per stampare big ints è una * pessima idea *. Si noti che l'output che si ottiene nell'ultima stampa concorda con l'output nella risposta accettata solo nelle prime 16 cifre. Se uno getta via tanta precisione, si può anche lavorare con i galleggianti. – kjo