Python rechnet nicht mit zu kleinen Zahlen?
Python 3.10
x = -2.7136680169203194e-30
y = 1.0
z = x + y
if z == y:
print("dumm")
output:
dumm
Was kann ich dagegen tun?
2 Antworten
Keine zu kleinen Zahlen verwenden.
Ist in jeder Programmiersprache so, nicht nur Python. double/float hat eben nur eine begrenzte Genauigkeit.
Ich würde versuchen, das Programm irgendwie umzuschreiben, sodass es diese Rechnung vermeidet.
Eventuell geht's mit Decimal: https://docs.python.org/3/library/decimal.html
Edit: Das hat wohl auch nur 28 Stellen Genauigkeit, anstatt der von dir gewünschten 30. Wenndann musst du also -2.7136680169203194e-28 hernehmen.
Man kann das Programm sicher irgendwie umschreiben, damit es nicht mit solchen kleinen Zahlen rechnet.
Nein, 28 ist nur der default, es sollte auch mehr gehen.
>>> a
Decimal('-2.7136680169203194E-30')
>>> b
Decimal('1')
>>> a+b
Decimal('0.9999999999999999999999999999972863319830796806')
Sieht auf den ersten Blick soweit okay aus.
Wie hast du das gemacht?
from decimal import Decimal
a = Decimal('-2.7136680169203194E-30')
b = Decimal('1')
print(b - a)
Bei mir gibt er 1.000000000000000000000000000 aus
Exemplarisch:
>>> con=decimal.Context(prec=128)
>>> decimal.setcontext(con)
......
Oder den Beispielen der Doku folgend, alles zusammen:
>>> import decimal
>>> decimal.getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
>>> decimal.getcontext().prec=512
>>> decimal.getcontext()
Context(prec=512, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
>>> a = decimal.Decimal('-2.7136680169203194E-30')
>>> b = decimal.Decimal(1)
>>> print(a+b)
0.9999999999999999999999999999972863319830796806
Dafür gibt es das Modul decimal:
Es müsste aber sicher auch einen Weg geben, um das mit sehr sehr kleinen Zahlen zu realisieren. Irgendwann nutzt man vielleicht ja doch mal eine