Thứ Tư, 20 tháng 2, 2019

Arithmetik mit beliebiger Genauigkeit - Wikipedia


In der Informatik willkürliche Arithmetik auch als bignum arithmetic bezeichnet, Multiple-Precision-Arithmetik oder manchmal Infinite-Precision-Arithmetik werden mit Zahlen ausgeführt, deren Ziffern nur durch den verfügbaren Speicher des Hostsystems begrenzt sind. Dies steht im Gegensatz zu der schnelleren Arithmetik mit fester Genauigkeit, die in der meisten Hardware für arithmetische Logikeinheiten (ALU) zu finden ist und normalerweise eine Genauigkeit von 8 bis 64 Bits bietet.

Mehrere moderne Programmiersprachen verfügen über eine integrierte Unterstützung für Bignums, andere bieten Bibliotheken für die Ganzzahl- und Fließkomma-Berechnung mit beliebiger Genauigkeit. Anstatt Werte als feste Anzahl von binären Bits zu speichern, die sich auf die Größe des Prozessorregisters beziehen, verwenden diese Implementierungen typischerweise Zahlenanordnungen mit variabler Länge.

Die willkürliche Genauigkeit wird in Anwendungen verwendet, in denen die Geschwindigkeit der Arithmetik kein einschränkender Faktor ist oder wenn genaue Ergebnisse mit sehr großen Zahlen erforderlich sind. Es sollte nicht mit der symbolischen Berechnung verwechselt werden, die von vielen Computeralgebra-Systemen bereitgestellt wird, die Zahlen durch Ausdrücke wie π · sin (2) darstellen und somit beliebige darstellen können Berechnungszahl mit unendlicher Genauigkeit.




Applications [ edit ]


Eine gebräuchliche Anwendung ist die Kryptographie mit öffentlichem Schlüssel, deren Algorithmen üblicherweise Arithmetik mit ganzen Zahlen mit Hunderten von Ziffern verwenden. [1][2] Eine andere ist in Situationen, in denen künstliche Grenzen bestehen und Überläufe wären unangemessen. Es ist auch nützlich, um die Ergebnisse von Berechnungen mit fester Genauigkeit zu überprüfen und um den optimalen Wert für Koeffizienten zu bestimmen, die in Formeln benötigt werden, z. B. 1/3 das bei der Gaußschen Integration auftritt.

Arbitrary Precision Arithmetic wird auch verwendet, um grundlegende mathematische Konstanten wie π zu Millionen oder mehr Ziffern zu berechnen und die Eigenschaften der Ziffernfolgen zu analysieren [3] oder allgemein das genaue Verhalten von Funktionen wie der Riemann-Zeta-Funktion zu untersuchen wo bestimmte Fragen mit analytischen Methoden schwer zu untersuchen sind. Ein anderes Beispiel ist das Rendern von fraktalen Bildern mit einer extrem hohen Vergrößerung, wie sie im Mandelbrot-Set zu finden sind.

Arithmetik mit beliebiger Genauigkeit kann auch verwendet werden, um Überlauf zu vermeiden, was eine inhärente Einschränkung der Arithmetik mit fester Genauigkeit ist. Ähnlich wie bei einer 5-stelligen Anzeige des Kilometerzählers, die sich von 99999 auf 00000 ändert, kann eine Ganzzahl mit fester Genauigkeit einen Wraparound aufweisen, wenn die Zahlen zu groß werden, um auf dem festgelegten Genauigkeitsniveau dargestellt zu werden. Einige Prozessoren können stattdessen mit Überlauf bis Sättigung umgehen, was bedeutet, dass ein Ergebnis, das nicht darstellbar wäre, durch den nächstgelegenen darstellbaren Wert ersetzt wird. (Bei einer vorzeichenlosen 16-Bit-Sättigung würde das Hinzufügen eines positiven Betrags zu 65535 zu 65535 führen.) Einige Prozessoren können eine Ausnahme generieren, wenn ein arithmetisches Ergebnis die verfügbare Genauigkeit überschreitet. Bei Bedarf kann die Ausnahme abgefangen und wiederhergestellt werden. Beispielsweise kann der Vorgang in der Software mit einer Arithmetik mit beliebiger Genauigkeit neu gestartet werden.

In vielen Fällen kann die Task oder der Programmierer garantieren, dass die ganzzahligen Werte in einer bestimmten Anwendung nicht groß genug werden, um einen Überlauf zu verursachen. Solche Garantien können sich auf pragmatische Grenzen stützen: Ein Schulbesuchsprogramm kann eine Aufgabengrenze von 4.000 Schülern haben. Ein Programmierer kann die Berechnung so gestalten, dass Zwischenergebnisse innerhalb der festgelegten Genauigkeitsgrenzen bleiben.

Einige Programmiersprachen wie Lisp, Python, Perl, Haskell und Ruby verwenden oder haben die Option, Zahlen mit beliebiger Genauigkeit für all all Integer-Arithmetik zu verwenden. Dies reduziert zwar die Leistung, beseitigt jedoch aufgrund eines einfachen Überlaufs möglicherweise falsche Ergebnisse (oder Ausnahmen). Dadurch kann auch garantiert werden, dass die arithmetischen Ergebnisse auf allen Maschinen gleich sind, unabhängig von der Wortgröße der jeweiligen Maschine. Die ausschließliche Verwendung von Zahlen mit beliebiger Genauigkeit in einer Programmiersprache vereinfacht auch die Sprache, da eine Zahl eine Zahl ist und es nicht erforderlich ist, dass mehrere Typen unterschiedliche Genauigkeitsstufen darstellen.


Implementierungsfragen [ edit ]


Die Arithmetik mit beliebiger Genauigkeit ist erheblich langsamer als die Arithmetik, wobei Zahlen verwendet werden, die vollständig in Prozessorregister passen, da die letzteren normalerweise in Hardware-Arithmetik implementiert sind muss in Software implementiert werden. Selbst wenn dem Computer für bestimmte Operationen (wie Integer-Division oder alle Gleitkomma-Operationen) keine Hardware zur Verfügung steht und stattdessen Software zur Verfügung gestellt wird, verwendet er Zahlengrößen, die eng mit den verfügbaren Hardware-Registern zusammenhängen: nur ein oder zwei Wörter und definitiv nicht N Wörter. Es gibt Ausnahmen, da bestimmte Maschinen mit variabler Wortlänge Maschinen der 1950er und 1960er Jahre, insbesondere die Serien IBM 1620, IBM 1401 und Honeywell Liberator die nur durch verfügbaren Speicher gebundenen Zahlen manipulieren konnten. mit einem zusätzlichen Bit, das den Wert begrenzt.

Zahlen können in einem Festkomma-Format oder in einem Fließkomma-Format als ein mit einem beliebigen Exponenten multiplizierter Signifikand gespeichert werden. Da jedoch die Division fast sofort unendlich wiederholte Ziffernfolgen (wie z. B. 4/7 in Dezimalzahl oder 1/10 in binärer Reihenfolge) einführt, sollte die Möglichkeit bestehen, dass entweder die Repräsentation auf eine zufriedenstellende Größe gekürzt wird oder rationalen Zahlen entsprechen used: eine große ganze Zahl für den Zähler und für den Nenner. Aber selbst wenn der größte gemeinsame Teiler ausgeteilt ist, kann die Arithmetik mit rationalen Zahlen sehr schnell unhandlich werden: 1/99 - 1/100 = 1/9900, und wenn 1/101 hinzugefügt wird, ist das Ergebnis 10001/999900.

Die Größe von Zahlen mit beliebiger Genauigkeit ist in der Praxis durch den verfügbaren Gesamtspeicher, die zum Indexieren der Ziffernfolgen verwendeten Variablen und die Berechnungszeit begrenzt. Ein 32-Bit-Betriebssystem kann den verfügbaren Speicher auf weniger als 4 GB beschränken. Eine Programmiersprache, die 32-Bit-Ganzzahlen verwendet, kann nur 4 GB indizieren. Wenn die Multiplikation mit einem O ( N 2 ) -Algorithmus durchgeführt wird, würde er in der Reihenfolge 10 12 zwei Schritte machen, um zwei zu multiplizieren Eine Million Wörter.

Zahlreiche Algorithmen wurden entwickelt, um arithmetische Operationen an Zahlen mit beliebiger Genauigkeit effizient durchzuführen. Unter der Annahme, dass N Ziffern verwendet werden, wurden insbesondere Algorithmen entwickelt, um die asymptotische Komplexität für große N zu minimieren.

Die einfachsten Algorithmen dienen der Addition und der Subtraktion, wobei man einfach die Ziffern in der Reihenfolge addiert oder subtrahiert und je nach Bedarf trägt, was einen Algorithmus von O ( N ) (19459009) ergibt O Notation).

Der Vergleich ist auch sehr einfach. Vergleichen Sie die höherwertigen Ziffern (oder Maschinenwörter), bis ein Unterschied gefunden wird. Ein Vergleich der restlichen Ziffern / Wörter ist nicht erforderlich. Der schlimmste Fall ist O ( N ) aber normalerweise wird es viel schneller gehen.

Für die Multiplikation erfordern die einfachsten Algorithmen, die für das Multiplizieren von Zahlen von Hand (wie in der Grundschule gelehrt) verwendet werden, O ( N 2 ) Operationen, aber Operationen O ( N log ( N ) log (log ( N ))) Komplexität wurden entwickelt, z. B. die Schönhage– Strassen-Algorithmus, basierend auf schnellen Fourier-Transformationen, und es gibt auch Algorithmen mit etwas schlechterer Komplexität, jedoch mit manchmal überlegener realer Leistung für kleinere N . Die Karatsuba-Multiplikation ist ein solcher Algorithmus.

Zur Division siehe Divisionsalgorithmus.

Eine Liste von Algorithmen mit Schätzungen der Komplexität finden Sie unter Rechenkomplexität mathematischer Operationen.

Beispiele für x86-Assemblys finden Sie unter externen Links.


Voreinstellungsgenauigkeit [ edit ]


In einigen Sprachen wie REXX muss die Genauigkeit aller Berechnungen eingestellt werden, bevor eine Berechnung ausgeführt wird. Andere Sprachen wie Python und Ruby erweitern die Genauigkeit automatisch, um einen Überlauf zu verhindern.


Beispiel [ edit ]


Die Berechnung von Fakultäten kann leicht sehr große Zahlen ergeben. Dies ist für ihre Verwendung in vielen Formeln (z. B. der Taylor-Reihe) kein Problem, da sie zusammen mit anderen Begriffen angezeigt werden, so dass Zwischenberechnungswerte bei sorgfältiger Beachtung der Reihenfolge der Auswertung nicht störend sind. Wenn Näherungswerte für faktorielle Zahlen gewünscht werden, liefert die Stirling-Näherung gute Ergebnisse unter Verwendung der Fließkomma-Arithmetik. Der größte darstellbare Wert für eine Integer-Variable mit fester Größe kann sogar für relativ kleine Argumente überschritten werden, wie in der nachstehenden Tabelle gezeigt. Sogar Fließkommazahlen werden bald überstiegen, so dass es hilfreich sein kann, die Berechnungen anhand des Logarithmus der Zahl neu zu erstellen.

Wenn jedoch exakte Werte für große Fakultäten gewünscht werden, ist eine spezielle Software erforderlich, wie im folgenden Pseudocode, der den klassischen Algorithmus zur Berechnung von 1, 1 × 2, 1 × 2 × 3, 1 × 2 × 3 implementiert × 4 usw. die aufeinanderfolgenden Faktorzahlen.


 Konstante Grenze = 1000; % Ausreichende Ziffern. 
Konstante Basis = 10; % Die Basis der simulierten Arithmetik.
Constant FactorialLimit = 365; % Zu lösende Zielnummer, 365!
Array-Ziffer [1:Limit] von Ganzzahl; % Die große Zahl.
Integer Carry, d; % Assistenten während der Vermehrung.
Ganzzahl zuletzt i; % Indizes zu den Ziffern der großen Zahl.
Feldtext [1:Limit] des Zeichens; % Scratchpad für die Ausgabe.
Constant tdigit [0:9] von Charakter = ["0","1","2","3","4","5","6","7","8","9"];
BEGIN
 Ziffer: = 0; % Löschen Sie das gesamte Array.
 Ziffer [1]: = 1; % Die große Zahl beginnt mit 1,
 letzte: = 1; % Die höchstwertige Stelle ist die Nummer 1.
für n: = 1 bis FactorialLimit do % Schritt durch die Produktion von 1 !, 2 !, 3 !, 4 !, etc.
  tragen: = 0; % Beginnen Sie eine Multiplikation mit n.
für i: = 1 bis last do % Schritt für Schritt jede Ziffer.
   d: = Ziffer [i] * n + Übertragen; % Der Klassiker multipliziert sich.
   Ziffer [i]: = d mod Basis; % Die niederwertige Stelle des Ergebnisses.
   tragen: = d div Basis; % Der Übertrag zur nächsten Ziffer.
weiter i;
   while carry> 0 % Speichern Sie den Carry in der großen Anzahl.
wenn letzte> = Grenze dann quaken ("Überlauf!"); % Wenn möglich!
   last: = last + 1; % Eine weitere Ziffer.
   Ziffer [last]: = Carry mod Basis; % platziert
   Carry: = Carry div Basis; % Der Carry reduzierte sich.
Wend % Bei n> Base möglicherweise mehr als eine Ziffer.
  Text: = ""; % Bereiten Sie nun die Ausgabe vor.
für i: = 1 bis zuletzt do % Übersetzen von binär in Text.
   Text [Limit - i + 1]: = tdigit [Ziffer[i]]; % Umkehrung der Reihenfolge.
weiter i; % arabische Ziffern setzen die niedrigste Ordnung.
Print Text, "=", n, "!"; % Ergebnis ausdrucken!
weiter n; % Weiter zur nächsten Fakultät
END ;

Mit dem betrachteten Beispiel können einige Details besprochen werden. Am wichtigsten ist die Wahl der Darstellung der großen Zahl. In diesem Fall sind für Zahlen nur ganzzahlige Werte erforderlich, sodass ein Array von Ganzzahlen mit fester Breite ausreicht. Es ist zweckmäßig, wenn aufeinanderfolgende Elemente des Arrays höhere Potenzen der Basis darstellen.

Die zweitwichtigste Entscheidung ist die Wahl der Basis der Arithmetik, hier zehn. Es gibt viele Überlegungen. Die Scratchpad-Variable d muss das Ergebnis einer einstelligen Multiplikation plus den Übertrag aus der Multiplikation der vorherigen Ziffer enthalten können. In der Basis 10 ist eine 16-Bit-Ganzzahl sicherlich ausreichend, da sie bis zu 32767 zulässt. Dieses Beispiel ist jedoch ein Betrug, da der Wert von n selbst nicht auf eine einzelne Ziffer beschränkt ist. Dies hat zur Folge, dass die Methode für n > 3200 oder so versagen wird. In einer allgemeineren Implementierung würde n auch eine mehrstellige Darstellung verwenden. Eine zweite Konsequenz der Abkürzung besteht darin, dass der letzte Wert von carry nach Abschluss der mehrstelligen Multiplikation möglicherweise in mehrere Ziffern höherer Ordnung, nicht nur in einen, übertragen werden muss.

Es gibt auch die Ausgabe des Ergebnisses in der Basis Zehn für den Menschen. Da die Basis bereits zehn ist, kann das Ergebnis einfach angezeigt werden, indem die aufeinanderfolgenden Ziffern von array digit gedruckt werden, sie werden jedoch mit der höchstwertigen Ziffer als letztes angezeigt (so dass 123 als "321" erscheint). . Das gesamte Array könnte in umgekehrter Reihenfolge gedruckt werden, aber dies würde die Nummer mit führenden Nullen ("00000 ... 000123") versehen, was möglicherweise nicht geschätzt wird. Daher haben wir uns entschieden, die Darstellung in einer mit Leerzeichen aufgefüllten Textvariablen zu erstellen und dann Drucken Sie das aus. Die ersten Ergebnisse (mit Abstand jeder fünften Ziffer und hier hinzugefügter Anmerkung) sind:
















































Fakultätsnummern
Reichweite von Computer-Ganzzahlen
1 = 1!
2 = 2!
6 = 3!
24 = 4!
120 = 5!
8-Bit 255
720 = 6!
5040 = 7!
40320 = 8!
16-Bit 65535
3 62880 = 9!
36 28800 = 10!
399 16800 = 11!
4790 01600 = 12!
32-Bit 42949 67295
62270 20800 = 13!
8 71782 91200 = 14!
130 76743 68000 = 15!
2092 27898 88000 = 16!
35568 74280 96000 = 17!
6 40237 37057 28000 = 18!
121 64510 04088 32000 = 19!
2432 90200 81766 40000 = 20!
64-Bit 18446 74407 37095 51615
51090 94217 17094 40000 = 21!
11 24000 72777 76076 80000 = 22!
258 52016 73888 49766 40000 = 23!
6204 48401 73323 94393 60000 = 24!
1 55112 10043 33098 59840 00000 = 25!
40 32914 61126 60563 55840 00000 = 26!
1088 88694 50418 35216 07680 00000 = 27!
30488 83446 11713 86050 15040 00000 = 28!
8 84176 19937 39701 95454 36160 00000 = 29!
265 25285 98121 91058 63630 84800 00000 = 30!
8222 83865 41779 22817 72556 28800 00000 = 31!
2 63130 83693 36935 30167 21801 21600 00000 = 32!
86 83317 61881 18864 95518 19440 12800 00000 = 33!
2952 32799 03960 41408 47618 60964 35200 00000 = 34!
128-Bit 3402 82366 92093 84634 63374 60743 17682 11455
1 03331 47966 38614 49296 66651 33752 32000 00000 = 35!

Wir könnten versuchen, die verfügbare Arithmetik des Computers effizienter zu nutzen. Eine einfache Eskalation wäre die Verwendung der Basis 100 (mit entsprechenden Änderungen des Übersetzungsprozesses für die Ausgabe) oder bei ausreichend breiten Computervariablen (z. B. 32-Bit-Ganzzahlen) könnten wir größere Basen wie z. B. 10.000 verwenden. Das Arbeiten in einer Zweierpotenz-Basis, die näher an den integrierten Ganzzahloperationen des Computers liegt, bietet Vorteile, obwohl die Konvertierung in eine Dezimalbasis für die Ausgabe schwieriger wird. Bei modernen Computern benötigen Additionen und Multiplikationen unabhängig von den Werten der Operanden eine konstante Zeit (solange die Operanden in einzelne Maschinenwörter passen), so dass große Gewinne erzielt werden, wenn in jedes Element des Moduls so viel Zahl wie möglich gepackt wird Ziffernfeld. Der Computer kann auch Möglichkeiten bieten, ein Produkt in eine Ziffer zu teilen und zu tragen, ohne die beiden Operationen von mod und div wie in dem Beispiel zu erfordern, und fast alle Recheneinheiten stellen bereit ] carry flag das bei Addition und Subtraktion mit mehrfacher Genauigkeit verwendet werden kann. Diese Art von Details ist das Fundament von Maschinencode-Programmierern, und eine geeignete Routine mit Montagesprache kann viel schneller ausgeführt werden als das Ergebnis der Kompilierung einer Hochsprache, die keinen Zugriff auf solche Einrichtungen bietet.

Für eine einstellige Multiplikation müssen die Arbeitsvariablen den Wert (Basis-1) halten können 2 + carry, wobei der Maximalwert des Carry (Basis-1) ist. In ähnlicher Weise sind die zum Indexieren des Ziffernfelds verwendeten Variablen selbst in der Breite begrenzt. Eine einfache Möglichkeit, die Indizes zu erweitern, besteht darin, die Ziffern der Zahl in Blöcken von geeigneter Größe zu behandeln, so dass die Adressierung über (Block i Ziffer j ) erfolgt, wobei ] i und j wären kleine Ganzzahlen, oder es könnte die Verwendung von Zahlentechniken für die Indizierungsvariablen eskalieren. Letztendlich setzen Maschinenspeicherkapazität und Ausführungszeit der Problemgröße Grenzen.


Geschichte [ edit ]


Der erste IBM-Computer von IBM, der IBM 702 (eine Vakuumröhrenmaschine) der Mitte der 1950er Jahre, implementierte ganzzahlige Arithmetik vollständig in Hardware auf Ziffernfolgen beliebiger Länge von 1 bis 511 Ziffern. Die früheste verbreitete Softwareimplementierung von Arbitrage mit beliebiger Genauigkeit war wahrscheinlich die in Maclisp. Später, um 1980, boten die Betriebssysteme VAX / VMS und VM / CMS Bignum-Funktionen als Sammlung von Stringfunktionen im einen Fall und in den Sprachen EXEC 2 und REXX im anderen.

Eine frühe, weit verbreitete Implementierung war über die IBM 1620 von 1959–1970 verfügbar. Die 1620 war eine dezimale Ziffernmaschine, die diskrete Transistoren verwendete, jedoch mit Hardware (die Nachschlagetabellen verwendete), um Ganzzahl-Arithmetik für Ziffernfolgen mit einer Länge auszuführen, die zwischen zwei und dem verfügbaren Speicherplatz liegen konnte. Bei der Fließkomma-Arithmetik wurde die Mantisse auf einhundert Stellen oder weniger und der Exponent auf nur zwei Ziffern beschränkt. Der größte gelieferte Speicher verfügte über 60 000 Ziffern. Fortran-Compiler für 1620 waren jedoch auf feste Größen wie 10 festgelegt, obwohl sie auf einer Kontrollkarte angegeben werden konnten, falls die Standardeinstellung nicht zufriedenstellend war.


Softwarebibliotheken [ edit ]



Arithmetik mit beliebiger Genauigkeit wird in den meisten Computersoftware implementiert, indem eine externe Bibliothek aufgerufen wird, die Datentypen und Subroutinen zum Speichern von Nummern mit der angeforderten Genauigkeit enthält Berechnungen durchführen.

Verschiedene Bibliotheken haben unterschiedliche Darstellungsmöglichkeiten für Zahlen mit beliebiger Genauigkeit. Einige Bibliotheken arbeiten nur mit Ganzzahlen, andere speichern Gleitkommazahlen in verschiedenen Basen (dezimale oder binäre Potenzen). Anstatt eine Zahl als Einzelwert darzustellen, speichern einige Zahlen Zahlen als Zähler / Nenner-Paar (Rationals) und andere können vollständig berechenbare Zahlen darstellen, allerdings nur bis zu einem bestimmten Speicherlimit. Grundsätzlich können Turingmaschinen nicht alle reellen Zahlen darstellen, da die Kardinalität von die Kardinalität von überschreitet.


Siehe auch [ edit ]


Referenzen [ bearbeiten



Externe Links [] .








Không có nhận xét nào:

Đăng nhận xét