Warum erhöht Pythons Float ValueError für einige sehr lange Eingaben?

8

Auf meiner Python 2.7.9 auf x64 sehe ich das folgende Verhalten:

%Vor%

Es sei denn, es gibt eine tiefere Begründung, die ich vermisse, das verletzt die wenigsten Überraschungen. Als ich den ValueError auf "10"*(2**29) bekam, dachte ich, dass es nur eine Einschränkung für sehr lange Strings war, aber dann funktionierte "0"*(2**33) . Was ist los? Kann jemand begründen, warum dieses Verhalten kein POLA-Fehler ist (wenn vielleicht ein relativ irrelevanter)?

    
FakeName123 21.06.2016, 02:52
quelle

2 Antworten

4

Da die Nullen beim Ableiten der Basis übersprungen werden

Ich schaue mir gerne meine bevorzugte Referenzimplementierung an für solche Fragen.

Der Beweis

Casevh hat eine große Intuition in den Kommentaren. Hier ist der relevante Code :

 %Vor%

Wo p anfänglich auf den Zeiger auf Ihre Zeichenfolge gesetzt ist. Wenn wir uns die Tabelle PyLongDigitValue ansehen, sehen wir, dass 0 explizit auf 0 abgebildet wird.

Python macht viel zusätzliche Arbeit, um die Konvertierung bestimmter Basen zu optimieren ( da ist ein Spaß 200 Zeile Kommentar über die Konvertierung binär !), Deshalb ist es eine Menge Arbeit, um zuerst die richtige Basis zu schließen. In diesem Fall; Wir können Nullen überspringen, wenn wir die Basis ableiten, so dass sie in der Überlaufberechnung nicht berücksichtigt werden.

Tatsächlich prüfen wir, wie viele Bits benötigt werden, um dieses Float zu speichern, aber Python ist schlau genug, um führende Nullen aus dieser Berechnung zu entfernen. Ich sehe in den Dokumenten der float-Funktion nichts, was dieses Verhalten über Implementierungen hinweg garantiert. Sie geben ominös an

  

Konvertiert einen String oder eine Zahl nach Möglichkeit in eine Fließkommazahl.

Wann funktioniert das nicht

Wenn Sie

schreiben %Vor%

Es hört früh auf, für die Basis zu analysieren - alle anderen Nullen werden in der Bitlängenberechnung berücksichtigt und tragen dazu bei, das ValueError

zu erhöhen

Ähnliche Analysetricks

Hier ist ein ähnlicher Fall in der Float-Klasse, wo wir das finden Whitespace wird ignoriert (und ein interessanter Kommentar der Autoren über ihre Absicht mit dieser Design-Wahl)

%Vor%     
en_Knight 21.06.2016, 03:26
quelle
2

Für den Fall von float ("10" * (2 ** 29)) konvertieren Sie die Zeichenfolge in einen Gleitkommawert, der höchstwahrscheinlich den Maximalwert überschreitet, den ein Gleitkomma in Python haben kann.

Für den Fall float ("0" * (2 ** 33)) konvertieren Sie den String in einen Gleitkommawert von 0.0, unabhängig davon, wie oft Sie ihn multiplizieren.

Der Fehler ist wegen der Beschränkung auf sehr lange Strings nicht aufgetreten, aber wegen der Begrenzung des maximalen Wertes von float.

Fühlen Sie sich frei, dies zu überprüfen Was ist die maximale Gleitzahl in Python?

    
Barry Lau 21.06.2016 03:26
quelle

Tags und Links