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)?
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
Ä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%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?
Tags und Links python