2009-09-14 3 views

Antwort

15

Siehe Math::BigInt

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

Ausgang:

760988023132059809720425867265032780727896356372077865117010037035791631439306199613044145649378522557935351570949952010001833769302566531786879537190794573523 
+0

Ace. Genau das, was ich brauchte. –

2

Mit Zahlen, die großen können Sie mehr Stellen als die Genauigkeit haben verwendet, um die Zahlen zu speichern. (Ein einfaches ausführbares Beispiel zu sehen, hätte diese Frage gelöst).

Wenn Sie wirklich alle 150+ Ziffern sehen müssen, sollten Sie die Module bigint (für ganze Zahlen), bigrat (für rationale Zahlen) und bignum (für Gleitkommazahlen) verwenden.

6

Wenn Sie es für alle ganzen Zahlen in Ihrem Programm tun möchten, können Sie einfach hinzufügen:

use bigint; 

Wenn Sie es nur für einige Zahlen tun möchten, können Sie Math::BigInt Objekte erstellen können.

Es gibt auch bignum und Math::BigNum, wenn Sie mit Floats arbeiten.

3

Für sehr kleine Werte finden Sie in den folgenden Code:

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

hat das gleiche Problem mit diesem Code:

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

Die letzten beiden Zeilen in dem Druck:

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

Offensichtlich nicht richtig, und nicht zu realisieren, dass die% d-Konvertierung das Problem verursacht, habe ich die Lösung hier markiert versucht:

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

Das war, als ich erkannte, dass die printf 'd' Konvertierung ein Problem verursachte. Lesen auf Math :: BigInt es scheint darauf hinzudeuten, dass diese Zahlen als Strings innerhalb gespeichert sind, so zu ändern, um ein ‚s‘ Umwandlung, das Problem behoben:

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

nun die letzten beiden richtig gedruckten Linien:

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

Aber in Bezug auf Karel Antwort, die IMHO fast korrekt war, könnte dies auch ohne die Verwendung von BigInt (bigint, BigNum, ... getan werden)) Durch die ‚f‘ Umwandlung verwenden, aber mit der Präzision auf ‚0‘ gesetzt, diese Dezimalstellen zu beseitigen:

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

Dies gilt auch für die Frage des OP funktioniert:

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

Die Verwendung von 'printf'% .0f \ n "' zum Drucken großer Schriften ist eine * wirklich * schlechte Idee. Beachten Sie, dass die Ausgabe, die Sie in Ihrem letzten Ausdruck erhalten, mit der Ausgabe in der angenommenen Antwort nur in den ersten 16 Ziffern übereinstimmt. Wenn man so viel Präzision wegwirft, kann man auch mit Schwimmern arbeiten. – kjo

Verwandte Themen