Dies ist vielleicht ein etwas hässlicher Hack, funktioniert aber ziemlich gut, wenn Sie nicht mehr als die Standard-Gleitkommagenauigkeit benötigen (etwa 11 Dezimalstellen).
Die round_to-Funktion verwendet die Format-Methode der integrierten str-Klasse, um die Gleitkommazahl auf eine Zeichenkette zu runden, die die Gleitkommazahl mit der erforderlichen Anzahl von Dezimalstellen darstellt, und wendet dann die integrierte Funktion eval auf die gerundete Gleitkommazahl-Zeichenkette an, um zum Gleitkommazahl-Numeriktyp zurückzukehren.
Die is_close-Funktion wendet einfach eine einfache Bedingung auf die aufgerundete Gleitkommazahl an.
def round_to(float_num, prec):
return eval("'{:." + str(int(prec)) + "f}'.format(" + str(float_num) + ")")
def is_close(float_a, float_b, prec):
if round_to(float_a, prec) == round_to(float_b, prec):
return True
return False
>>>a = 10.0
10.0
>>>b = 10.0001
10.0001
>>>print is_close(a, b, prec=3)
True
>>>print is_close(a, b, prec=4)
False
Update:
Wie von @stepehjfox vorgeschlagen, ein saubererer Weg, um eine round_to-Funktion zu erstellen, die "eval" vermeidet, ist die Verwendung von verschachtelter Formatierung:
def round_to(float_num, prec):
return '{:.{precision}f}'.format(float_num, precision=prec)
Dem gleichen Gedanken folgend kann der Code sogar noch einfacher sein, wenn die großartigen neuen f-Strings (Python 3.6+) verwendet werden:
def round_to(float_num, prec):
return f'{float_num:.{prec}f}'
Also könnten wir alles sogar in einer einfachen und sauberen Funktion 'is_close' zusammenfassen:
def is_close(a, b, prec):
return f'{a:.{prec}f}' == f'{b:.{prec}f}'
0 Stimmen
@tolomea: Da es von Ihrer Anwendung, Ihren Daten und Ihrem Problem abhängt - und es sich nur um eine Zeile Code handelt -, warum sollte es eine "Standardbibliotheksfunktion" geben?
14 Stimmen
@S.Lott:
all
,any
,max
,min
sind im Grunde genommen Einzeiler, und sie werden nicht nur in einer Bibliothek bereitgestellt, sondern sind eingebaute Funktionen. Die Gründe des BDFL sind also nicht das. Die eine Zeile Code, die die meisten Menschen schreiben, ist ziemlich einfallslos und funktioniert oft nicht, was ein starkes Argument dafür ist, etwas Besseres bereitzustellen. Natürlich müsste ein Modul, das andere Strategien bietet, auch Warnhinweise bereitstellen, wann sie angemessen sind und vor allem wann nicht. Numerische Analyse ist schwierig, es ist kein großes Unglück, dass Sprachdesigner normalerweise keine Tools zur Unterstützung dabei entwickeln.0 Stimmen
@Steve Jessop. Diese sammlungsbasierten Funktionen haben nicht die Anwendungs-, Daten- und Problemdomänenabhängigkeiten wie Gleitkommazahlen. Daher ist der "Einzeiler" offensichtlich nicht so wichtig wie die eigentlichen Gründe. Die numerische Analyse ist schwierig und kann kein integraler Bestandteil einer Library einer allgemeinen Zwecksprache sein.
7 Stimmen
@S.Lott: Ich würde wahrscheinlich zustimmen, wenn die Standard-Python-Distribution nicht mit mehreren Modulen für XML-Schnittstellen geliefert würde. Offensichtlich ist die Tatsache, dass verschiedene Anwendungen etwas unterschiedlich machen müssen, überhaupt kein Hindernis dafür, Module in den Basissatz aufzunehmen, um es auf die eine oder andere Weise zu tun. Sicherlich gibt es Tricks zum Vergleichen von Gleitkommazahlen, die häufig wiederverwendet werden, wobei der grundlegendste eine bestimmte Anzahl von ulps ist. Also stimme ich nur teilweise zu - das Problem ist, dass numerische Analyse schwierig ist. Python könnte grundsätzlich Werkzeuge bereitstellen, um es etwas einfacher zu machen, zumindest manchmal. Ich denke, niemand hat sich bisher freiwillig gemeldet.
0 Stimmen
@Steve Jessop. Es hängt zu sehr von Ihrer Anwendung und Ihren Daten und Ihrem Problemfeld ab. Da es letztlich auf eine schwer zu gestaltende Codezeile hinausläuft, fügen die Bibliotheken nicht viel hinzu. Ein Buch wie Numerical Recipes in Python wäre hilfreicher als eine Bibliothek, die schwierige Probleme banalisiert.
0 Stimmen
@S.Lott: Also, ich denke, die Frage ist, ob der Code in diesem Buch tatsächlich nützlich ist. Wenn ja, gibt es keinen speziellen Grund, warum es nicht eine Bibliothek sein könnte, obwohl zugegebenermaßen Personen, die das Buch nicht gelesen haben, Schwierigkeiten haben könnten, es korrekt zu verwenden. Auf der anderen Seite können Personen, die ein Buch über Unicode nicht gelesen haben,
str
leicht falsch verwenden. Wenn Sie erst einmal eine Bibliothek mit wertvollen Tools haben, könnte beurteilt werden, ob sie zu den üblichen Kriterien gehört. Der Unterschied zwischen beispielsweise Textverarbeitung (sehr anwendungs- und datenspezifisch) und numerischer Verarbeitung besteht darin, wie viele Personen diese benötigen.4 Stimmen
Ebenfalls heißt es "es läuft auf eine schwer zu gestaltende Codezeile hinaus" - wenn es immer noch ein Einzeiler ist, wenn du es richtig machst, denke ich, dass dein Monitor breiter ist als meiner ;-). Wie dem auch sei, ich halte das gesamte Gebiet für ziemlich spezialisiert, im Sinne, dass die meisten Programmierer (einschließlich mir) es sehr selten verwenden. In Verbindung mit der Schwierigkeit wird es also nicht ganz oben auf der "meistgesuchten" Liste für Kernbibliotheken in den meisten Sprachen stehen.
0 Stimmen
@S.Lott Bisher scheinen wir nur zwei praktikable Lösungen zu haben, von denen eine nur gültig ist, wenn Sie die Größenordnung der Eingaben kennen. Sicher müssen die Epsilon-Werte je nach Anwendung angepasst werden, aber sie sind Argumente.
0 Stimmen
Vielleicht möchten Sie Ihren Link aktualisieren, randomascii.wordpress.com/2012/02/25/…
0 Stimmen
Nie hatte solche Probleme mit Matlab, warum?
0 Stimmen
@bonobo Vielleicht gibst du nicht genug Mühe stackoverflow.com/questions/23824577/…