So, jetzt hat mich das hier so oft diskutierte Thema "Runden" auch erwischt, denn eine Kollegin hat in einem Zins- und Tilgungsplan entdeckt, dass bei einer "glatten" 5 als dritte Dezimalstelle gelegentlich an der 2. Nachkommastelle abgerundet wird.
Also habe ich den Vorschlag von Marco aufgegriffen und in einer Klasse eine Funktion wie folgt erstellt:
Private Const conModule = "clsRound."
Public Class clsRound
... div. Private & Public Properties + Sub New ...
Public Function roundValue(Byval dInputValue As Double, Byval iDigits As Integer) As Boolean
On Error Goto processError
Dim sMethod As String
sMethod = "roundValue: "
roundValue = False
Dim dTmpVal1 As Double, dTmpVal2 As Double, dTmpVal3 As Double, dDigits As Double, dAdd As Double
dDigits = 10^iDigits
dAdd = 0.50
dTmpVal1 = dInputValue * dDigits
dTmpVal2 = dTmpVal1 + dAdd
dTmpVal3 = Fix(dTmpVal2)
dResult = dTmpVal3 / dDigits
roundValue = True
exitFunction:
Exit Function
processError:
sErrorString = conModule & sMethod & " Allgem. Fehler: " & Str(Err) & " " & Error$ & " Zeile: " & Str(Erl)
Resume exitFunction
End Function 'roundValue
...End Class
Die vielen Zwischenvariablen sind erst nach und nach entstanden, denn das Ergebnis stimmte leider nicht immer :(
Bei einem übergebenem Wert 322.194,925 wurde richtigerweise 322.194,93 zurückgegeben.
Für 285.146,225 erhielt ich jedoch 285.146,22!
Diverse Prints zeigten folgende Werte:
dInputValue = 285146,225
dTmpVal1 = 28514622,5
dTmpVal2 = 28514623
dTmpVal3 = 28514622
dResult = 285146,22
D.h. bei dem Fix() wurde die scheinbare Ganzzahl ...23 auf ...22 geändert. Diverse Eingriffe (z.B. statt 0.5 eine Addition mit 1/2 etc.) haben nix gebracht.
Ein Print von Fraction(dTmpVal2) zeigte dann unerwartet statt ,0 einen Wert von ,999999967usw.
Unschöne, aber funktionierende Lösung:
dTmpVal = Cdbl(Cstr(dTmpVal1 + dAdd))
Das Parsen in einen String und wieder zurück in einen Double sorgt bei allen Werten für korrekte Ergebnisse.