Multiplikation mit *0.01 ergibt .xx0000000000001

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
nieselfriem
User
Beiträge: 135
Registriert: Sonntag 13. Januar 2013, 16:00

Hallo,

ich Preise von Artikeln in einer Datenbank in Centangaben. Das heißt also bei 8,95€ sind das 895 Cent. Nun will ich z.B. auf der Rechnung die preise in Euro ausgeben. Dazu führe ich folgendes aus:

Code: Alles auswählen

>>> unit_cost=895
>>> preis = unit_cost*0.01
>>> print(preis)
8.950000000000001
wieso wird bei dem Preis die 0000000000001 angehangen und wie kann ich das verhindern?

denn bei 1995 passiert das nicht: :?

Code: Alles auswählen

>>> unit_cost=1995
>>> preis = unit_cost*0.01
>>> print(preis)
19.95
VG niesel
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Floatingpoint-Zahlen haben nur eine begrenzte Genauigkeit. Bei Preisen nimmt man normalerweise das Decimal-Modul. Alternativ gibt man die Zahlen formatiert auf zwei Nachkommastellen aus, da ist aber das Problem, wenn die Zahlen sehr groß werden, oder viele zusammengerechnet werden, das Ergebnis ungenau wird.
Benutzeravatar
__blackjack__
User
Beiträge: 13107
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nieselfriem: Doch, auch bei 1995 passiert das, weil man 0.01 schon nicht exakt als `float` darstellen kann. Sieht man, wenn man sich mal mehr Nachkommastellen anzeigen lässt als das die normale `repr()`-Darstellung macht:

Code: Alles auswählen

In [10]: f'{0.01:.60f}'
Out[10]: '0.010000000000000000208166817117216851329430937767028808593750'

In [11]: f'{1995 * 0.01:.60f}'
Out[11]: '19.949999999999999289457264239899814128875732421875000000000000'
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Übrigens wird das Problem dadurch verstärkt, dass schon 0.01 nicht exakt darstellbar ist, und sich die Fehler (0.01 ungenau, Ergebnis auch nicht genau darstellbar) verstärken.
Schreibt man 895 / 100, wird 8.95 ausgegeben.

Code: Alles auswählen

In [12]: f"{895 / 100:0.20f}"
Out[12]: '8.94999999999999928946'

In [13]: f"{895 * 0.01:0.20f}"
Out[13]: '8.95000000000000106581'

In [14]: 895 / 100
Out[14]: 8.95
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Ich hatte das gleiche Problem und die Werte als Cent gespeichert, um Kommazahlen zu vermeiden.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Antworten