You are here: Perldoc Web>PerlDokumentListe>Perlnumber (2009-10-03)
perlnumber Dokumentation zu Perl 5.9.2 | Download als POD | Wie kann ich hier etwas ändern?
perlnumber - Semantik von Zahlen und numerischen Operationen in Perl

ÜBERSICHT

    $n = 1234;              # Dezimale Ganzzahl
    $n = 0b1110011;         # Binäre Ganzzahl
    $n = 01234;             # Oktale Ganzzahl
    $n = 0x1234;            # Hexadezimale Ganzzahl
    $n = 12.34e-56;         # Exponentialdarstellung
    $n = "-12.34e56";       # Zahl als Zeichenkette dargestellt
    $n = "1234";            # Zahl als Zeichenkette dargestellt

BESCHREIBUNG

Dieses Dokument beschreibt, wie Perl intern mit Zahlwerten umgeht.

Auf die Möglichkeit, in Perl Operatoren zu überladen, wird hier nicht eingegangen. Das Überladen von Operatoren erlaubt benutzerdefiniertes Verhalten für Zahlen, wie beispielsweise Berechnungen mit beliebig langen Ganzzahlen, Fließkommazahlen mit beliebiger Genauigkeit oder Berechnungen mit "exotischen" Zahlen, wie Modulo-Arithmetik oder p-adische Arithmetik. Siehe overload für Details.

Zahlen speichern

Perl kann Zahlen intern auf drei verschiedene Arten speichern: als native Ganzzahlen, als native Fließkommazahlen und als dezimale Zeichenketten. Dezimale Zeichenketten können einen Exponenzialteil in der Notation haben, wie in "12.34e-56" . Nativ bedeutet hier "ein Format, welches von dem C-Compiler unterstützt wird, mit dem Perl übersetzt wurde".

Die Bezeichnung "nativ" ist für die Diskussion von nativen Ganzzahlen nicht so entscheidend wie für native Fließkommazahlen. Die einzige Auswirkung, die der Begriff "nativ" auf Ganzzahlen hat, ist die Beschränkung für die größte und die kleinste echte ganzzahlige Größe auf Werte nahe einer Zweierpotenz. "Native" Fließkommazahlen dagegen haben eine grundlegende Einschränkung: Mit ihnen kann man nur die Zahlen darstellen, die eine relativ "kurze" Darstellung haben, wenn man sie in einen Binärbruch umwandelt. So kann zum Beispiel 0.9 nicht als native Fließkommazahl dargestellt werden, da der Binärbruch für 0.9 unendlich ist:

    binär0.1110011001100...

wobei sich die Folge 1100 immer wiederholt. Zusätzlich zu dieser Einschränkung ist auch der Exponent einer Binärzahl begrenzt, wenn sie als Fließkommazahl dargestellt wird. Auf typischer Hardware können Fließkommazahlen Werte mit bis zu 53 Binärstellen und Exponenten zwischen -1024 und 1024 speichern. Dies entspricht in dezimaler Darstellung ungefähr 16 Dezimalziffern und Dezimalexponenten zwischen -304 und 304. Kurz gesagt kann Perl eine Zahl wie 12345678901234567 auf solchen Architekturen nicht ohne Informationsverlust als Fließkommazahl speichern.

Ganz ähnlich können dezimale Zeichenketten nur jene Zahlen darstellen, die eine endliche dezimale Darstellung haben. Da es sich um Zeichenketten handelt, und diese beliebige Länge haben können, gibt es bei diesen Zahlen keine praktische Grenze für den Exponenten oder die Anzahl von Dezimalstellen. (Man sollte sich aber darüber im Klaren sein, dass diese Regeln nur für das Speichern dieser Zahlen gelten. Die Tatsache, dass man solche "großen" Zahlen speichern kann, bedeutet nicht, dass Operationen mit diesen Zahlen alle signifikanten Ziffern nutzen. Siehe Numerische Operationen und numerische Umwandlungen für Details.)

Eigentlich können im nativen Ganzzahlformat gespeicherte Zahlen entweder als vorzeichenbehaftete native Form oder als nicht-vorzeichenbehaftete native Form vorliegen. Daher liegen die Grenzen für native Ganzzahlen in Perl typischerweise bei -2**31 .. 2**32-1, mit entsprechend angepassten Werten für 64-bit-Ganzzahlen. Auch hier bedeutet dies nicht, dass Perl nur mit Ganzzahlen in diesem Bereich rechnen kann: Im Fließkommaformat lassen sich viele weitere Ganzzahlen speichern.

Kurz gesagt lassen sich nur diese Zahlenwerte in Perl speichern, die eine endliche dezimale oder eine "kurze" binäre Darstellung haben.

Numerische Operationen und numerische Umwandlungen

Wie bereits angemerkt, kann Perl Zahlen in einem von drei Formaten ablegen, aber die meisten Operatoren verstehen normalerweise nur eines dieser Formate. Wenn ein Zahlwert an einen dieser Operatoren als Argument übergeben wird, wird er in das vom Operator verstandene Format umgewandelt.

Es gibt sechs solche Umwandlungen:

  native Ganzzahl       --> native Fließkommazahl   (*)
  native Ganzzahl       --> dezimale Zeichenkette
  native Fließkommazahl --> native Ganzzahl         (*)
  native Fließkommazahl --> dezimale Zeichenkette   (*)
  dezimale Zeichenkette --> native Ganzzahl
  dezimale Zeichenkette --> native Fließkommazahl   (*)

Diese Umwandlungen gehorchen den folgenden allgemeinen Regeln:

  • Wenn die Quellzahl in der Zielform dargestellt werden kann, wird diese Darstellung genutzt.

  • Wenn die Quellzahl außerhalb der Grenzen liegt, die von der Zielform dargestellt werden kann, wird eine Darstellung des nächsten Grenzwertes benutzt. ( Informationsverlust )

  • Wenn die Quellzahl zwischen zwei Zahlen liegt, die in der Zielform dargestellt werden können, wird die Darstellung einer dieser Zahlen benutzt. ( Informationsverlust )

  • Bei der Umwandlung native Fließkommazahl --> native Ganzzahl ist die Größenordnung des Ergebnisses kleiner oder gleich der Größenordnung der Quelle. ( "Runden zur Null hin" )

  • Wenn die Umwandlung dezimale Zeichenkette --> native Ganzzahl nicht ohne Informationsverlust durchgeführt werden kann, dann ist ist das Ergebnis kompatibel mit der Umwandlungsfolge dezimale Zeichenkette --> native Fließkommazahl --> native Ganzzahl . Insbesondere ist die Rundung stark zur 0 hin gewichtet, wobei aber eine Zahl wie "0.99999999999999999999" eine Chance hat, zur 1 hin gerundet zu werden.

EINSCHRÄNKUNG : Die Umwandlungen, die oben mit (*) markiert wurden, beinhalten Schritte, die vom C-Compiler durchgeführt werden. Insbesondere können Bugs oder Features des Compilers dazu führen, dass eine oder mehrere der obigen Regeln gebrochen werden.

Arten von numerischen Operationen in Perl

Operationen, an die ein numerisches Argument übergeben werden kann, behandeln dieses Argument auf eine von vier verschiedenen Arten: sie können es in eines der Ganzahl-/Fließkommazahl-/Zeichenkettenformate zwingen, oder sie können sich in Abhängigkeit vom Format des Operanden unterschiedlich verhalten. Wenn ein numerischer Wert in ein bestimmtes Format gezwungen wird, ändert das nicht die Zahl, die in diesem Wert gespeichert ist.

Alle Operatoren, die ein Argument im Ganzzahlformat benötigen, behandeln dieses Argument wie in Modulo-Arithmetik, d.h. mod 2**32 auf einer 32-Bit-Architektur. sprintf "%u", -1 gibt daher das gleiche Ergebnis wie sprintf "%u", ~0 .

Arithmetische Operatoren

Die binären Operatoren + - * / % ==   !   => < >= <= und die unären Operatoren - , abs und -- versuchen, ihre Argumente in Ganzzahlen umzuwandeln. Wenn beide Umwandlungen ohne Verlust von Genauigkeit möglich sind und die Operation ohne Verlust von Genauigkeit durchgeführt werden kann, dann wird das Ganzzahlergebnis genutzt. Andernfalls werden die Argumente in Fließkommaformat umgewandelt und das Fließkommaergebnis wird genutzt. Das Zwischenspeichern von Umwandlungen (wie oben beschrieben) bedeutet, dass die Ganzzahlumwandlung keine Nachkomma-Anteile von Fließkommazahlen wegwirft.

++

++ verhält sich wie die anderen Operatoren oben, außer wenn das Argument eine Zeichenkette ist, die das Format /^[a-zA-Z]*[0-9]*\z/ hat. Dann wird das Zeichenketten-Inkrement aus perlop benutzt.

Arithmetische Operatoren unter use integer

Im Geltungsbereich von use integer; erzwingen fast alle oben genannten Operatoren ihr(e) Argument(e) in das Ganzzahlformat und geben ein Ganzzahlergebnis zurück. Nur abs , ++ und -- ändern ihr Verhalten unter use integer; nicht.

Andere mathematische Operatoren

Operatoren wie ** , sin oder exp zwingen ihre Argumente in das Fließkommaformat.

Bitweise Operatoren

Argument werden in das Ganzzahlformat gezwungen, wenn es keine Zeichenketten sind.

Bitweise Operatoren unter use integer

erzwingen ihre Argumente ins Ganzzahlformat. Auch benutzen shift-Operationen intern vorzeichenbehaftete Ganzzahlen anstelle der sonste genutzten nicht-vorzeichenbehafteten.

Operatoren, die eine Ganzzahl erwarten,

erzwingen ihre Argumente in das Ganzzahlformat. Dies gilt beispielweise für das dritte und vierte Argument von sysread .

Operatoren, die eine Zeichenkette erwarten,

erzwingen ihre Argumente in das Zeichenkettenformat. Dies gilt beispielweise für printf "%s", $wert .

Auch wenn die erzwungene Umwandlung eines Argumentes in eine bestimmte Form die gespeicherte Zahl nicht ändert, merkt sich Perl das Ergebnis einer solchen Umwandlung. Dies bedeutet, dass zwar die erste solche Umwandlung zeitraubend sein kann, aber wiederkehrende Operationen die Umwandlung nicht wiederholen müssen.

AUTOR

Ilya Zakharevich <ilya@math.ohio-state.edu>

Redaktionelle Korrekturen durch Gurusamy Sarathy <gsar@ActiveState.com>

Updates für 5.8.0 durch Nicholas Clark <nick@ccl4.org>

ÜBERSETZUNG

Übersetzung durch Harald Bongartz <dubu {ät} perl-community.de>

SIEHE AUCH

overload, perlop


Kommentare:

-- HaraldBongartz - 29 Jun 2003
-- HaraldBongartz - 08 Sep 2009
Topic revision: r4 - 2009-10-03 - 18:05:51 - HaraldBongartz
 
Bitte die NutzungsBedingungen beachten.
Bei Vorschlägen, Anfragen oder Problemen mit dem PerlCommunityWiki bitten wir um WebBottomBarExample">Rückmeldung.