Nicht wirklich spezifisch für die Implementierung von Python, sollte aber für alle Float-to-Decimal-String-Funktionen gelten.
Eine Gleitkommazahl ist im Wesentlichen eine Binärzahl, jedoch in wissenschaftlicher Notation mit einer festen Grenze signifikanter Zahlen.
Die Umkehrung einer Zahl mit einem Primzahlfaktor, der nicht mit der Basis geteilt wird, führt immer zu einer wiederkehrenden Punktpunktdarstellung. Zum Beispiel hat 1/7 einen Primfaktor 7, der nicht mit 10 geteilt wird, und hat daher eine wiederkehrende Dezimaldarstellung, und dasselbe gilt für 1/10 mit den Primfaktoren 2 und 5, wobei letzterer nicht mit 2 geteilt wird ;; Dies bedeutet, dass 0,1 nicht genau durch eine endliche Anzahl von Bits nach dem Punktpunkt dargestellt werden kann.
Da 0.1 keine exakte Darstellung hat, versucht eine Funktion, die die Approximation in eine Dezimalzeichenfolge konvertiert, normalerweise, bestimmte Werte zu approximieren, damit sie keine unintuitiven Ergebnisse wie 0.1000000000004121 erhalten.
Da der Gleitkomma in wissenschaftlicher Notation vorliegt, wirkt sich jede Multiplikation mit einer Potenz der Basis nur auf den Exponententeil der Zahl aus. Zum Beispiel 1.231e + 2 * 100 = 1.231e + 4 für die Dezimalschreibweise und ebenso 1.00101010e11 * 100 = 1.00101010e101 in der Binärschreibweise. Wenn ich mit einer Nicht-Potenz der Basis multipliziere, werden auch die signifikanten Ziffern beeinflusst. Zum Beispiel 1.2e1 * 3 = 3.6e1
Abhängig vom verwendeten Algorithmus wird möglicherweise versucht, gemeinsame Dezimalstellen nur anhand der signifikanten Zahlen zu erraten. Sowohl 0,1 als auch 0,4 haben die gleichen signifikanten Zahlen in binärer Form, da ihre Floats im Wesentlichen Kürzungen von (8/5) (2 ^ -4) bzw. (8/5) (2 ^ -6) sind. Wenn der Algorithmus das 8/5-Sigfig-Muster als Dezimalzahl 1,6 identifiziert, funktioniert er mit 0,1, 0,2, 0,4, 0,8 usw. Es kann auch magische Sigfig-Muster für andere Kombinationen geben, z. B. Float 3 geteilt durch Float 10 und andere magische Muster, die statistisch wahrscheinlich durch Division durch 10 gebildet werden.
Im Fall von 3 * 0,1 unterscheiden sich die letzten signifikanten Zahlen wahrscheinlich von der Division eines Floats 3 durch Float 10, was dazu führt, dass der Algorithmus die magische Zahl für die Konstante 0,3 abhängig von seiner Toleranz für Präzisionsverlust nicht erkennt.
Bearbeiten:
https://docs.python.org/3.1/tutorial/floatingpoint.html
Interessanterweise gibt es viele verschiedene Dezimalzahlen, die denselben ungefähren binären Bruchteil haben. Beispielsweise werden die Zahlen 0.1 und 0.10000000000000001 und 0.1000000000000000055511151231257827021181583404541015625 alle durch 3602879701896397/2 ** 55 angenähert. ) == x.
Es gibt keine Toleranz für Präzisionsverluste. Wenn float x (0,3) nicht genau gleich float y (0,1 * 3) ist, ist repr (x) nicht genau gleich repr (y).