Discussion:
Fehler in Berechnung Addition und Multiplikation von Zahlen
(zu alt für eine Antwort)
Dennis George
2008-12-05 11:08:06 UTC
Permalink
Hallo zusammen,

ich benutzer Access 2003 um Reports zu generieren und muss dort natürlich
auch mal etwas berechnen. Nur leider macht Access hier etwas nicht richtig.
Beispiel ist folgende Rechnung:

274.8 - (6 * 45.8)

Sollte eigendlich 0 rauskommen. Access gibt mir jedoch folgendes Ergebnis:

2,8421709430404E-14

Hat jemand eine Ahnung warum das so ist und -- viel wichtiger -- wie ich das
beheben kann??

Viele Grüße

Dennis George
Jörg Ackermann
2008-12-05 11:18:19 UTC
Permalink
Hallo,
Post by Dennis George
Hallo zusammen,
ich benutzer Access 2003 um Reports zu generieren und muss dort
natürlich auch mal etwas berechnen. Nur leider macht Access hier
274.8 - (6 * 45.8)
2,8421709430404E-14
Hat jemand eine Ahnung warum das so ist und -- viel wichtiger -- wie
ich das beheben kann??
guckst Du:
www.donkarl.com?FAQ2.1

Gruß
Andreas Vogt
2008-12-05 11:26:44 UTC
Permalink
Hallo,
Hängt vom Datentyp ab, bei LongInteger ist das Ergebnis = 0
Das Problem liegt bei den Nachkommastellen die im Dualsystem nicht
linear errechnet werden können, sondern theoretisch bei unendlicher
Kaskadierung genau rechnen würde. Aber Access bricht bei x Stellen ab,
daher kommts zum Fehler.

Das muss man entsprechend berücksichtigen beim weiterrechnen.

Gruß Andreas
Andreas Vogt
2008-12-05 11:29:42 UTC
Permalink
Oder auch hier eine Erklärung von Reinhard:
"Gleitkommazahlen (auch Double!) haben nun einmal nur eine endliche
Genauigkeit. Und da sie intern als Dualzahlen dargestellt werden,
lassen sich Rundungsfehler bei der Konversion in Dezimalzahlen nicht
immer vermeiden..."

Ingrid
Thomas Winkler
2008-12-05 11:35:28 UTC
Permalink
Hi,
Post by Dennis George
ich benutzer Access 2003 um Reports zu generieren und muss dort natürlich
auch mal etwas berechnen. Nur leider macht Access hier etwas nicht richtig.
274.8 - (6 * 45.8)
2,8421709430404E-14
2,8 * 10^-14 ist doch 0.
Post by Dennis George
Hat jemand eine Ahnung warum das so ist und -- viel wichtiger -- wie ich das
beheben kann??
Das ist so, weil man mit einer endlichen Anzahl Bit (sagen wir mal 32,
z.B. bei Single) keine unendlich genaue Abbildung einer Zahl darstellen
kann. Der unendlich große Wertebereich von +unendlich bis -unendlich
wird erstmal durch den Datentyp eingegrenzt (Single: -3,402823E38 bis
-1,401298E-45 und 1,401298E-45 bis 3,402823E38) Dieser Wertebereich wird
dann in 2^32 diskrete "Punkte" zerlegt, die darstellbar sind.

Hast Du nun eine Zahl, die nicht exakt einen dieser diskreten Punkte
trifft, muss sie gerundet werden. Das kann nun dazu führen, dass Deine
45.8 intern als 45.8000000000001 dargestellt werden muss. Durch die
Multiplikation versechsfacht sich der Fehler und fällt dann auf.

1. Verwende Double anstatt Single

Das löst das Problem zwar nicht grundsätzlich, aber könnte im Einzelfall
helfen.

2. Nachdenken

Wenn eine Ganzahl (0 Nachkommastellen) mit einer Zahl (1
Nachkommastellen) Multipliziert wird, kann das Ergebnis nur 1
Nachkommastellen haben. Also sollte ein

Round(<ErgebnisDeinerRechnung>, 1)

das gewünschte Ergebnis liefern.

Ansonsten sollte als Faustregel für den zweiten Rundungsparameter gelten:

Max(x, 1) * Max(y, 1)

mit

x = Anzahl Nachkommastellen erste Zahl
y = Anzahl Nachkommastellen zweite Zahl

.

HTH

Thomas

--
"Access? Damit arbeite ich nicht. Das ist doch nur ein abgespecktes Excel."
Dennis George
2008-12-05 12:09:01 UTC
Permalink
Hallo!

Danke erst einmal für die Antworten. Die Lösung mit dem Runden hat geholfen.
Trotzdem ein etwas komisches Verhalten von Access. In vb.net macht der das
nicht so!

Viele Grüße
Dennis George
Post by Dennis George
Hallo zusammen,
ich benutzer Access 2003 um Reports zu generieren und muss dort natürlich
auch mal etwas berechnen. Nur leider macht Access hier etwas nicht richtig.
274.8 - (6 * 45.8)
2,8421709430404E-14
Hat jemand eine Ahnung warum das so ist und -- viel wichtiger -- wie ich das
beheben kann??
Viele Grüße
Dennis George
Thomas Winkler
2008-12-05 12:21:18 UTC
Permalink
Hi,
Post by Dennis George
Trotzdem ein etwas komisches Verhalten von Access. In vb.net macht der das
nicht so!
Halte ich für ein Gerücht. Auch vb.net hat nur eine begrenzte Anzahl an
Bit für eine Zahl zur Verfügung. Vielleicht tritt das Problem bei o. g.
Beispielrechnung nicht auf (weil die diskreten Punkte anders verteilt
sind) aber grundsätzlich gilt das auch für vb.net.

Thomas

--
"Access? Damit arbeite ich nicht. Das ist doch nur ein abgespecktes Excel."
Josef Poetzl
2008-12-05 14:12:54 UTC
Permalink
Hallo!
Post by Dennis George
Danke erst einmal für die Antworten. Die Lösung mit dem Runden hat geholfen.
Trotzdem ein etwas komisches Verhalten von Access. In vb.net macht der das
nicht so!
Wie hast du das unter vb.net probiert?
Debug.Print(274.8 - (6 * 45.8))
=> 5,6843418860808E-14

Das war VBA mit 2,8421709430404E-14 sogar näher bei 0. :-))

Nimmt man jedoch einen anderen Datentyp, kann durchaus 0 herauskommen:
unter vb.net: 274.8D - (6D * 45.8D)
unter VBA: cdec(274.8) - cdec(6.0) * cdec(45.8)

Ob es sinnvoll ist, will ich nicht beurteilen.

mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Thomas Möller
2008-12-06 09:16:47 UTC
Permalink
Hallo Dennis,
Post by Dennis George
Post by Dennis George
ich benutzer Access 2003 um Reports zu generieren und muss dort natürlich
auch mal etwas berechnen. Nur leider macht Access hier etwas nicht richtig.
274.8 - (6 * 45.8)
2,8421709430404E-14
Hat jemand eine Ahnung warum das so ist und -- viel wichtiger -- wie ich das
beheben kann??
Danke erst einmal für die Antworten. Die Lösung mit dem Runden hat geholfen.
Du kommst auch ohne eigene Runden-Funktion aus:

Dim Erg As Currency

Erg = 274.8 - (6 * 45.8)

Debug.Print Erg


Schau dazu Dir bitte in der Online-Hilfe die Beschreibung zum Datentyp
Currency näher an. Der ist extra für solche Fälle da.

CU
--
Thomas

Homepage: www.Team-Moeller.de
Loading...