2009-09-14 33 views

Respuesta

15

Ver Math::BigInt

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

Salida:

760988023132059809720425867265032780727896356372077865117010037035791631439306199613044145649378522557935351570949952010001833769302566531786879537190794573523 
+0

Ace. Justo lo que necesitaba. –

2

Con un número tan grande que pueda tener más dígitos que la precisión se utiliza para almacenar los números. (Ver un simple ejemplo ejecutable habría resuelto esta pregunta).

Si realmente necesita ver los más de 150 dígitos, debe utilizar los módulos bigint (para enteros), bigrat (para números racionales) y bignum (para números flotantes).

6

Si desea hacerlo para todos los enteros en su programa, sólo se puede añadir:

use bigint; 

Si sólo desea que lo haga por algunos números enteros, puede crear objetos Math::BigInt.

También está bignum y Math::BigNum si está trabajando con flotadores.

3

Para valores muy pequeños ver el siguiente código:

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

Tenía el mismo problema con este código:

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

Las dos últimas líneas donde la impresión:

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

Obviamente no es correcto, y al no darme cuenta de que la conversión% d estaba causando el problema, intenté con la solución marcada aquí:

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

Fue entonces cuando me di cuenta de que la conversión de printf 'd' estaba causando un problema. Leyendo sobre Matemáticas :: Bigint parece sugerir que estos números se almacenan como cadenas en el interior, por lo que cambiar a una conversión 's', ha solucionado el 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); 
} 

Ahora las dos últimas líneas imprimen correctamente:

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

Pero en cuanto a la respuesta de Karel, que era casi correcta en mi humilde opinión, esto también podría hacerse sin el uso de BigInt (Bigint, BigNum, ...) Mediante el uso de la conversión 'f', pero con la precisión pone a '0' para eliminar esos decimales:

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

Esto también funciona para la pregunta del OP:

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

Usar 'printf"% .0f \ n "' para imprimir grandes cantidades es una * realmente * mala idea. Tenga en cuenta que la salida que obtiene en su última impresión está de acuerdo con el resultado en la respuesta aceptada solo en los primeros 16 dígitos. Si uno va a tirar tanta precisión, uno también puede trabajar con flotadores. – kjo

Cuestiones relacionadas