Seite 1 von 1
Mathefehler in Python?
Verfasst: Dienstag 26. Mai 2020, 18:41
von Kidney
Servus Leute!
Ich habe angefangen Python zu lernen und bin auf etwas seltsames gestoßen.
Lange Rede kurzer Sinn. Seht selbst:
Code: Alles auswählen
print("can Python really calculate?", 2.4 * 6)
print("The result should be 14.40")
Python wirft als Ergebnis NICHT 14.40 aus, sondern 14.399999999999999.
Warum ist das so? Ist das nur auf meinem Rechner so?
Vielen Dank!
PS:
Anderer Test mit Unterhaltungswert:
Code: Alles auswählen
result = 2.4 * 6
if result == 14.40:
print("Yes!")
else:
print("Python: Es tut mir leid, ich war noch nie gut in Mathe.")
Re: Mathefehler in Python?
Verfasst: Dienstag 26. Mai 2020, 18:48
von __deets__
Das hat mit Python und deinem Rechner nichts zu tun. Das liegt an der Fliesskommazahlendarstellung nach IEEE754, die bei den meisten Computern und Programmiersprachen zum Einsatz kommt. Und die basiert zum einen auf dem binaersystem, und hat zum anderen eine begrenzte Genauigkeit. Und daher kommt es, das Zahlen, die im Dezimalsystem ganz leicht darstellen koennen, viel mehr Nachkommastellen brauchen. Und dadurch auch Rundungsfehler einfuehren.
Wenn man mit Fliesskommazahlen arbeitet, kann man darum (und auch aus vielen anderen Gruenden) ueblicherweise nicht mit == arbeiten, sondern muss den Vergleich mit einer gewissen Ungenauigkeit machen. Auch als Vergleich mit Epsilon bezeichnet:
Code: Alles auswählen
if abs(result - 14.40) < kleines_epsilon:
print("ich bin ausreichend gut in Mathe")
Re: Mathefehler in Python?
Verfasst: Dienstag 26. Mai 2020, 20:27
von __blackjack__
Wobei das `math`-Modul da schon eine Funktion für hat:
Code: Alles auswählen
In [281]: import math
In [282]: math.isclose(2.4 * 6, 14.4)
Out[282]: True
Und das Problem ist das 2.4 schon nicht exakt dargestellt werden kann. Sieht man, wenn man sich davon mal mehr Nachkommastellen anzeigen lässt:
Code: Alles auswählen
In [284]: format(2.4, ".50f")
Out[284]: '2.39999999999999991118215802998747676610946655273438'
Eine weitere Möglichkeit diese Ungenauigkeit auf Kosten von Rechenzeit zu umgehen ist das `decimal`-Modul:
Code: Alles auswählen
In [285]: from decimal import Decimal
In [286]: Decimal("2.4") * 6 == Decimal("14.4")
Out[286]: True
Oder man arbeitet mit Brüchen:
Code: Alles auswählen
In [288]: from fractions import Fraction
In [289]: Fraction(24, 10)
Out[289]: Fraction(12, 5)
In [290]: Fraction(144, 10)
Out[290]: Fraction(72, 5)
In [291]: Fraction(24, 10) * 6
Out[291]: Fraction(72, 5)
Re: Mathefehler in Python?
Verfasst: Mittwoch 27. Mai 2020, 04:52
von snafu
Ich finde hier ja das schon erwähnte isclose() am hilfreichsten. Wenn einem das lieber ist, dann lässt sich der Funktion ein Alias vergeben:
Code: Alles auswählen
from math import isclose as is_equal
if is_equal(2.4 * 6, 14.4):
print("Richtig gerechnet")
else:
print("Falsch gerechnet")
Oder man "versteckt" den Aufruf hinter eine eigene Funktion:
Code: Alles auswählen
from math import isclose
def calc(calculation, result):
if isclose(calculation, result):
print("Richtig gerechnet")
else:
print("Falsch gerechnet")
Re: Mathefehler in Python?
Verfasst: Mittwoch 27. Mai 2020, 06:17
von Kidney
Wow, super! Vielen Dank für die Antworten! Wie komplex dann doch scheinbar einfache Gegebenheiten in der Informatik sein können
