Fließkomma rechnen mit Micropython: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
Peter (Diskussion | Beiträge) |
Peter (Diskussion | Beiträge) |
||
Zeile 220: | Zeile 220: | ||
Mit dem Umweg über Integer: | Mit dem Umweg über Integer: | ||
<pre> | <pre> | ||
# float_test_001.py | |||
# | |||
# Addiert Fließkommazahlen mit verschiedenen Methoden | |||
# | |||
faktor = 1e5 | |||
int_step = int(step*faktor) | |||
step = 0.00005 | |||
x_add = 0.0 | |||
x_mul = 0.0 | |||
x_int = 0 | |||
for i in range(300): | |||
x_add += step | |||
x_mul = step*(i+1) | |||
x_int = ((x_int * faktor) + int_step) / faktor | |||
print(f'{i:5}: {x_add:<12} {x_mul:<12} {x_int:<12}') | |||
</pre> | </pre> | ||
Zeile 233: | Zeile 252: | ||
>>> | >>> | ||
</pre> | </pre> | ||
=== Lösung mit Stringformatierung=== | === Lösung mit Stringformatierung=== | ||
Noch 'ne Möglichkeit: | Noch 'ne Möglichkeit: |
Version vom 18. März 2025, 12:14 Uhr
Das Rechnen mit Fließkommazahlen bringt immer Ungenauigkeiten mit sich.
Additions-/Rundungsfehler
Gerade bin ich auf einen Effekt bei der Addition von vielen Fließkommazahlen mit einem M5Stack gestoßen:
Additionsfehler
>>> step = 0.00005 >>> x = 0.0 >>> for i in range(1000): x += step print(x) # Ergebnisse: 5e-05 0.0001 0.00015 0.0002 0.00025 0.0003 0.00035 0.0004 0.00045 0.0005 0.00055 0.0005999999 0.0006499999 0.0006999999 0.0007499999 0.0007999998 0.0008499998 0.0008999997 0.0009499997 0.0009999997 0.00105 0.0011 0.00115 0.0012 0.00125 ... 0.0024 0.00245 0.0025 0.002549999 0.002599999 0.002649999 ... 0.003749997 0.003799997 0.003849998 0.003899997 0.003949997 ... 0.007049992 0.007099992 0.007149992 0.007199991 0.007249992 0.007299991 0.007349991 0.007399991
Multipikationsfehler
Mit einer Multiplikation statt Addition ist das Ergebnis befriedigender:
>>> for i in range(1000): x = step*i print(x) # Ergebnisse: 0.0 5e-05 0.0001 0.00015 0.0002 0.00025 0.0003 0.00035 0.0004 0.00045 0.0005 0.00055 0.0006 0.00065 0.0007 0.00075 0.0008 0.0008499999 0.0009 0.00095 0.0009999999 0.00105 0.0011 0.00115 0.0012 0.00125 ... 0.0052 0.00525 0.0053 0.005349999 0.0054 0.00545 0.0055 ... 0.0056 0.00565 0.005699999 0.00575 0.0058 ... 0.006 0.00605 0.006099999 0.00615 0.0062 ... 0.0065 0.00655 0.006599999 0.00665 0.0067 0.00675 0.006799999 0.006849999 0.0069 0.00695 0.007 0.007049999 0.0071 0.007150001 0.0072 0.00725 0.0073 0.007349999 0.0074 0.00745 ... 0.00775 0.0078 0.007849999 0.0079 0.00795 0.008 0.008049999 0.0081 0.00815 0.008200001 0.008249999 0.0083 0.008349999 0.0084 0.008450001 0.008499999 0.008549999 0.008599999 0.00865 0.0087 0.00875 ... 0.00895 0.009 0.009049999 0.009099999 0.009149999 0.0092 0.00925 ... 0.00945 0.0095 0.009549999 0.009599999 0.00965 0.0097 ... 0.0409 0.04095 0.04099999 0.04105 0.0411 ... 0.0442 0.04425 0.04429999 0.04435 0.0444 ... 0.0453 0.04535 0.04539999 0.04545 0.0455 0.04555 0.04559999 0.04565 0.0457 ... 0.0488 0.04885 0.04889999 0.04895 0.049 0.04905 0.0491 0.04914999 0.0492 0.04925 0.0493 0.04934999 0.0494 0.04945 ... 0.04975 0.0498 0.04985 0.0499 0.04995 >>>
Verbesserung durch Integer
Mit dem Umweg über Integer:
# float_test_001.py # # Addiert Fließkommazahlen mit verschiedenen Methoden # faktor = 1e5 int_step = int(step*faktor) step = 0.00005 x_add = 0.0 x_mul = 0.0 x_int = 0 for i in range(300): x_add += step x_mul = step*(i+1) x_int = ((x_int * faktor) + int_step) / faktor print(f'{i:5}: {x_add:<12} {x_mul:<12} {x_int:<12}')
Der Fehler entsteht durch die Summierung:
# in der Schleife: 101: 0.0051 102: 0.00514999 # als einzelne Berechnung in der REPL: >>> 0.0051+0.00005 0.00515 >>>
Lösung mit Stringformatierung
Noch 'ne Möglichkeit:
>>> a = f'{0.0009999999:.5f}' >>> a '0.00100' >>> float(a) 0.001 >>>