Python: Rechnen

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
reneschmidt
User
Beiträge: 48
Registriert: Montag 4. Januar 2016, 15:14

Hallo zusammen,

folgendes Problem:
Ich habe Zahlen (Buchungen in EURO) die als String aus einer Datenbank lese:
2019-07-01 42.2 0
2019-07-01 -27.5 0
2019-07-01 -41.9 0
2019-07-01 27.2 0

Gesamt MG: SOLL: 3.552713678800501e-15 IST: 0.0

Ich rechne mit Python die zweite spalte zusammen und erhalte nicht 0 sondern 3.552713678800501e-15

die Brechungen sieht wie folgt aus:

Code: Alles auswählen

for ein in sqlre:
			if ein[3] != ein[4]:
				soll = ein[3]
				ist = ein[4]

				print ("    " + str(ein[1]) + "   " + soll + "       " + ist)
				
				sollge = sollge + float(soll)
				istge = istge + float(ist)
		print("  Gesamt MG: SOLL: " + str(sollge) + "  IST: " + str(istge))
Kann mir jemand sagen, warum ich nicht 0 erhalte?
Wie kann ich es schaffen, das Python immer nur mit 2 Nachkommastellen arbeitet?

wenn ich mit round(2) arbeite, erhalte ich nur AttributeError: 'float' object has no attribute 'round'
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Willkommen in der wunderbaren Welt der Gleitkommazahlen. Durch die beschraenkte Genauigkeit und die Unmoeglichkeit jede Zahl in jedem System praezise darzustellen kommt es zu solchen Rundungsfehlern.

Es gibt verschieden Wege, damit umzugehen:

- benutz decimal.Decimal. Das funktionert fuer dein Beispiel, aber zB 1/3 ist auch in Decimal unendlich gross, und somit ist 3 * (1/3) auch nicht 1, so wie man es sich wuenschen wuerde. Aber die Rungungsregeln und signifikanten Stellen sind wenigstens dezimal.
- runden bei der Ausgabe. Dazu zB die Format-Strings und deren Moeglichkeit, nur beschraenkt viele Stellen auszugeben betrachten.

Code: Alles auswählen

import decimal
values = [
          "42.2",
          "-27.5",
          "-41.9",
          "27.2",
          ]


fvalues = [float(v) for v in values]
print("sum(fvalues)", sum(fvalues), "{:0.2f}".format(sum(fvalues)))

dvalues = [decimal.Decimal(v) for v in values]
print("sum(dvalues)", sum(dvalues))
Sirius3
User
Beiträge: 17761
Registriert: Sonntag 21. Oktober 2012, 17:20

@reneschmidt: warum hast Du Strings in einer Datenbank. Man würde ja erwarten, dass da ein Datumsfeld und schon zwei Decimalzahlen drin stehen.

Welche Datenbank benutzt Du denn da und woher kommen die Daten?
reneschmidt
User
Beiträge: 48
Registriert: Montag 4. Januar 2016, 15:14

Hallo zusammen,
Vielen Dank für die Info.
Ich werde es nächste Woche mal probieren.

Zum Hintergrund. Die Tabelle die ich abgreife wird durch einen auswertungslauf gefüllt.

Theoretisch wäre es möglich das in der Spalte auch zb Euro steht.
Da die Auswertung bei uns definitiv nur zahlen liefert, muss ich da so mit umgehen
Sirius3
User
Beiträge: 17761
Registriert: Sonntag 21. Oktober 2012, 17:20

Das erklärt aber nicht, warum die Tabelle designt ist. Da muß man den Auswertungslauf eben auch reparieren.Für Euro kennen die meisten Datenbanken den Typ CURRENCY.
Antworten