Rechenfehler oder Brett vorm Kopf?

macht mal ein Form mit einem Textcontrol (Text1) und versucht mal folgenden Code:

Option Explicit

Private Sub Form_Load()
Dim X As Double
X = 5.03
Text1.Text = X - 5
End Sub

Da sollte doch eigentlich 0.03 bei rauskommen, bei mir ergibt das aber 3,00000000000002E-02.

VB6 SP4

hat jemand eine Erklärung dafür??

Da sollte doch eigentlich 0.03 bei rauskommen, bei mir ergibt
das aber 3,00000000000002E-02.

Das kommt daher, dass VB (und andere Programmiersprachen) die Zahlen intern in Birärdarstellung speichern. Dabei treten immer kleine Rundungsdifferenzan auf.
Die beste Lösung ist daher, Fließkommazahlen immer auf eine bestimmte Stellenanzahl zu runden.
z.B. a=round(a*100)/100 um auf 2 Stellen zu runden

aha.
ist das mit SP5 genauso?

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

aha.
ist das mit SP5 genauso?

Ich denke mal, daß die Art, wie gerechnet wird, durch die Hardware (sprich, den binären Prozessor) festgelegt ist. Mit einem SP könnte man höchstens filtern, aber wo soll man da den Grenzwert zwischen sinnvoll und sinnlos ziehen?

Du wirst also selbst filtern müssen. Entweder durch Rundung, wie zuvor beschrieben, oder auch durch Formatierung mit Hilfe der Format-Funktion. Als Argument erwartet die neben dem Wert selbst einen Zeichenkette, die den gleichen Aufbau hat wie jene, die man bei Format/Cells/Numbers[Custom] verwendet (benutzerdefiniertes Zahlenformat; siehe dazu die VBA-Hilfe; [Strg]-[F1]). Ergebnis ist natürlich eine Zeichenkette, die man aber ggf. wieder in eine Zahl umwandeln kann. Für das Textfeld ist das ja egal.

Achso, wenn ich weiß, daß ich höchstens 2 oder 3 Kommastellen erhalte, kann ich auch auf z.B. 8 Stellen runden. Dann kommt statt 0.30000000000001 immernoch 0.3 raus, aber ich laufe nicht Gefahr, mehr Stellen abzuschneiden als ich will (falls es doch mal eine mehr wird).

Kristian

Ich denke mal, daß die Art, wie gerechnet wird, durch die
Hardware (sprich, den binären Prozessor) festgelegt ist. Mit
einem SP könnte man höchstens filtern, aber wo soll man da den
Grenzwert zwischen sinnvoll und sinnlos ziehen?

ist richtig, aber es gibt ja einfache Alghoritmen, die die Maschinengenauigkeit bestimmen, und vielleicht sind die ja in einem SP an solchen Stellen integriert.
Und da ich noch mit SP4 arbeite und noch keine Beschreibung der Änderungen / Verbesserungen durch SP5 gefunden habe, wäre das ja mal ein Punkt.

Hast Du SP5 drauf und könntest das mal kurz testen, bitte?

Gruß Norbert

das ist in SP5 sicher nicht „korrigiert“, da dies schliesslich kein Bug ist, sondern die ganz normale Behandlung des Datentyps Double.

Hallo!

Schnipp:

Da sollte doch eigentlich 0.03 bei rauskommen, bei mir ergibt
das aber 3,00000000000002E-02.

hat jemand eine Erklärung dafür??

Ja.

Auch Brüche (Zahlen mit Nachkommastellen) werden binaer im Speicher abgelegt:

5,03 = ... 0\*2^3 + 1\*2^2 + 0\*2^1 + 1\*2^0 + 0\*2^(-1) + 0\*2^(-2) + ...
 0 + 4 + 0 + 1 + 0 + 0 +
...
... 1\*2^(-6) + 1\*2^(-7) + 1\*2^(-8) + ...
... 0,03 ~ 0,015625 + 0,0078125 + 0,00390625 + ...

Wenn Du also 5,03 im Speicher ablegen willst und dabei den Datentyp Double verwendest, ensteht durch das Abspeichern im binärformat eine ‚Rundungsdifferenz‘.

Das Ergebnis ist also völlig korrekt.

Auch SP5, 6 … wird daran nichts ändern.

Einziger Ausweg: Zahlen anders abspeichern und andere Algorithmen zur genauen Berechnung verwenden.

Gruss
Thomas