Wie kann ich die wissenschaftliche Schreibweise deaktivieren, wenn mit sehr großen Zahlen in Perl zu arbeiten?

StackOverflow https://stackoverflow.com/questions/1424317

Frage

Beachten Sie Folgendes:

print 3 ** 333; #Yields 7.6098802313206e+158

Meine Frage ist einfach: Wie kann ich die wissenschaftliche Schreibweise zu deaktivieren, wenn mit sehr großen Zahlen zu arbeiten? Im Grunde möchte ich alle Ziffern sehen abgeladen wörtlich stdout.

Ist das möglich?

War es hilfreich?

Lösung

Siehe Math::BigInt

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

Ausgabe:

760988023132059809720425867265032780727896356372077865117010037035791631439306199613044145649378522557935351570949952010001833769302566531786879537190794573523

Andere Tipps

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 erstellen Objekte.

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

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

Mit Zahlen, die großen Sie mehr Ziffern haben kann als die Genauigkeit der Zahlen zu speichern, verwendet. (Ein einfaches runnable Beispiel sehen würde diese Frage gelöst hat).

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

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 denen Druck:

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

Offensichtlich nicht richtig, und nicht die% D-Umwandlung realisiert wurde das Problem verursacht, versuchte ich die Lösung hier gekennzeichnet:

#!/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 ist, wenn ich die printf ‚d‘ realisierte Umwandlung ein Problem verursacht wurde. Lesen auf Math :: BigInt es scheint darauf hinzudeuten, dass diese Zahlen als Strings innerhalb gespeichert sind, verändert sich so zu einem ‚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 sind die letzten beiden Zeilen gedruckt korrekt:

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

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

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

Das funktioniert auch für die Frage des OP:

perl -e 'printf "%.0f\n", 3 ** 333'
760988023132059813486251563646478824265752535077884574263917414498578085812167738721447369281049109603746001743233145041176969930222526036520619613114171654144
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top