it-swarm.com.de

Wie bekomme ich größtmögliche Präzision? (Python - Dezimal)

Ich verwende die Klasse Decimal für Operationen, die Präzision erfordern.

Ich möchte die größtmögliche Präzision verwenden. Damit meine ich so genau wie das System, auf dem das Programm läuft, handhaben kann.

Um eine bestimmte Genauigkeit festzulegen, ist es einfach:

import decimal
decimal.getcontext().prec = 123 #123 decimal precision

Ich habe versucht, die maximale Genauigkeit herauszufinden, die die Klasse "Decimal" berechnen kann:

print(decimal.MAX_PREC)
>> 999999999999999999

Also habe ich versucht, die Präzision auf die höchste Genauigkeit zu setzen (zu wissen, dass es wahrscheinlich nicht funktioniert.):

decimal.getcontext().prec = decimal.MAX_PREC

Aber natürlich wirft dies einen Memory Error (auf Division)

Meine Frage ist also: Wie finde ich heraus, mit welcher Präzision das aktuelle System umgehen kann?

Zusatzinformation:

import sys
print(sys.maxsize)
>> 9223372036854775807
10
Eli

Dies zu versuchen ist ein Fehler. Ein Problem mit mehr Präzision zu lösen, ist für Neulinge, die sich mit dem Fließkomma-Punkt beschäftigen, eine verlockende Falle, die aber gerade in diesem Extrem nicht besonders nützlich ist.

Ihre Operationen würden nicht die "größtmögliche" Präzision erfordern, selbst wenn dies eine klar definierte Vorstellung wäre. Entweder benötigen sie genau - Arithmetik. In diesem Fall ist decimal.Decimal das falsche Werkzeug, und Sie sollten sich etwas wie fractions.Fraction oder symbolische Berechnung anschauen, oder sie erfordern nicht so viel Präzision Sie brauchen tatsächlich und verwenden Sie das.

Wenn Sie immer noch die größtmögliche Genauigkeit für Ihr Problem verwenden möchten, hängt die Genauigkeit der Berechnung davon ab, welche Art von Mathematik Sie verwenden, und wie viele absurd genaue Zahlen Sie gleichzeitig im Speicher speichern möchten . Dies kann durch die Analyse Ihres Programms und der Speicheranforderungen von Decimal-Objekten ermittelt werden. Alternativ können Sie die Genauigkeit als Parameter und die binäre Suche nach der größten Genauigkeit verwenden, die keinen Absturz verursacht.

9
user2357112

Ich möchte eine Funktion vorschlagen, mit der Sie Ihre maximale Genauigkeit für eine bestimmte Operation auf brutale Weise abschätzen können:

def find_optimum(a,b, max_iter):
    for i in range(max_iter):
        print(i)
        c = int((a+b)/2)
        decimal.getcontext().prec = c
        try:
            dummy = decimal.Decimal(1)/decimal.Decimal(7) #your operation
            a = c
            print("no fail")
        except MemoryError:
            print("fail")
            dummy = 1
            b = c
        print(c)
        del dummy

Dies ist nur eine Halbierung der Intervalle Schritt für Schritt und prüft, ob ein Fehler auftritt. Ein Aufruf mit max_iter=10 und a=int(1e9), b=int(1e11) ergibt:

>>> find_optimum(int(1e9), int(1e11), 10)
0
fail
50500000000
1
no fail
25750000000
2
no fail
38125000000
3
no fail
44312500000
4
fail
47406250000
5
fail
45859375000
6
no fail
45085937500
7
no fail
45472656250
8
no fail
45666015625
9
no fail
45762695312

Dies kann eine grobe Vorstellung von dem geben, mit dem Sie sich befassen. Bei i5-3470 und 16 GB RAM dauerte dies ungefähr eine halbe Stunde, sodass Sie es wirklich nur zu Testzwecken verwenden würden. 

Ich glaube nicht, dass es tatsächlich eine exakte Methode gibt, die maximale Präzision für Ihre Operation zu erzielen, da Sie genau wissen müssen, wie stark die Speichernutzung von der Speichernutzung abhängt. Ich hoffe, das hilft Ihnen wenigstens ein bisschen und ich würde wirklich gerne wissen, wofür Sie diese Präzision brauchen.

EDITIch denke, das muss wirklich hinzugefügt werden, da ich hier Ihre Kommentare unter dem am besten bewerteten Beitrag gelesen habe. Die Verwendung einer willkürlich hohen Genauigkeit auf diese Weise ist nicht der Weg, auf dem Konstanten berechnet werden. Sie würden etwas programmieren, das Speicherplatz auf intelligente Weise ausnutzt (z. B. Berechnen einer Reihe von Ziffern in RAM und Schreiben dieser Menge in eine Textdatei), verwenden Sie jedoch niemals nur RAM/Swap, da dies immer der Fall ist Begrenzen Sie Ihre Ergebnisse. Mit modernen Algorithmen zur Berechnung von Pi benötigen Sie keinen unendlichen Arbeitsspeicher. Sie müssen lediglich eine weitere 4-TB-Festplatte in die Maschine einlegen und die nächsten Ziffern schreiben. Soweit für mathematische Konstanten.

Nun zu den physikalischen Konstanten: Sie sind nicht genau. Sie sind auf Messungen angewiesen. Ich bin mir nicht sicher, ob atm (wird editieren), aber ich denke, dass die physikalische Konstante most einen Fehler von 10 ** (- 8) hat. Wenn Sie mehr Präzision darauf werfen, wird es nicht genauer, Sie berechnen lediglich mehr falsche Zahlen.

Als Experiment war dies eine lustige Idee, weshalb ich die Antwort sogar überhaupt veröffentlicht habe.

4
user8408080

Die maximale Genauigkeit der Decimal-Klasse hängt vom Speicher des Geräts ab. Es gibt daher keine gute Möglichkeit, diese Einstellung für den allgemeinen Fall festzulegen. Grundsätzlich ordnen Sie den gesamten Arbeitsspeicher einer Maschine einer Variablen zu, um maximale Präzision zu erzielen.

Wenn die mathematische Operation dies unterstützt, können Sie mit langen Ganzzahlen eine unbegrenzte Genauigkeit erzielen. Sie sind jedoch auf ganze Zahlen beschränkt.

Additionen, Subtraktionen, Multiplikationen und einfache Exponenten können mit langen Ganzzahlen exakt ausgeführt werden.

Vor Python 3 führte der integrierte Datentyp long Berechnungen mit beliebiger Genauigkeit aus https://docs.python.org/2/library/functions.html#long

In Python> = 3 stellt der Datentyp int jetzt lange Ganzzahlen dar https://docs.python.org/3/library/functions.html#int

Ein Beispiel für eine 64-Bit-Ganzzahl-Mathematik ist die Implementierung von Bitcoind, bei der für die Berechnungen von Transaktionen exakte Werte erforderlich sind. Die Genauigkeit der Bitcoin-Transaktionen ist jedoch auf 1 "Satoshi" begrenzt. Jedes Bitcoin ist als 10 ^ 8 (Ganzzahl) Satoshi definiert.

Die Decimal-Klasse funktioniert ähnlich unter der Haube. Eine Dezimalgenauigkeit von 10 ^ -8 entspricht dem Bitcoin-Satoshi-Paradigma.

2
Chris Hubley

Aus Ihrer Antwort oben:

Was wäre, wenn ich einfach mehr Ziffern in Pi suchen wollte als bereits gefunden? Was wäre, wenn ich die Irrationalität von e oder Mills Konstante testen wollte.

Ich verstehe es. Ich mache wirklich Meine one SO question , mehrere Jahre alt, handelt von Gleitkommabibliotheken mit beliebiger Genauigkeit für Python. Wenn dies die Arten von numerischen Darstellungen sind, die Sie generieren möchten, müssen Sie sich auf den Tiefgang vorbereiten. Dezimal/FP-Arithmetik ist notorisch schwierig in der Informatik. 

Einige Programmierer denken, wenn sie mit einem Problem konfrontiert sind: „Ich weiß, ich verwende Gleitkomma-Arithmetik.“ Jetzt haben sie 1.999999999997 Probleme. - @tomscott

Ich denke, wenn andere gesagt haben, es sei ein "Fehler" oder "es kommt darauf an", sich zu fragen, wie hoch die maximale Genauigkeit für einen Python Decimal-Typ auf einer bestimmten Plattform ist, nehmen sie Ihre Frage wörtlicher, als ich vermute, dass sie beabsichtigt war. Sie haben nach dem Python-Decimal-Typ gefragt, aber wenn Sie an FP Arithmetik für Bildungszwecke - "um mehr Ziffern in pi zu finden" - interessieren, werden Sie leistungsfähigere, flexiblere Werkzeuge benötigen als Dezimal oder Float . Diese integrierten Python-Typen kommen nicht einmal close. Das ist gut genug für die NASA, aber sie hat Grenzen ... in der Tat die Grenzen, nach denen Sie fragen.

Dafür gibt es Fließkommabibliotheken mit mehrfacher Genauigkeit (oder beliebige Genauigkeit ): willkürlich genaue Darstellungen. Möchten Sie pi für die nächsten 20 Jahre berechnen? Pythons Decimal-Typ bringt Sie nicht einmal durch day.

Tatsache ist, dass die binäre Multi-Precision-Arithmetik FP immer noch eine Randwissenschaft ist. Für Python müssen Sie die Bibliothek GNU MPFR auf Ihrer Linux-Box installieren. Anschließend können Sie die Python-Bibliothek gmpy2 verwenden, um so tief zu tauchen, wie Sie möchten. 

Die Frage ist nicht: "Was ist die maximale Präzision, die mein Programm verwenden kann?"

"Wie schreibe ich mein Programm, damit es läuft, bis der Strom ausgeht?"

Und das ist ein ganz anderes Problem, aber zumindest ist es durch Ihren Algorithmus eingeschränkt, nicht durch die Hardware, auf der es läuft.

0
Joseph8th