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
Ace. Justo lo que necesitaba. –