Wir stoßen auf ein Problem mit VB.NET Math.Round
Methode, wo wir verschiedene Ergebnisse für die gleiche Eingabe erhalten.VB.net Math.Round Rundungsproblem - verschiedene Ergebnisse für die gleiche Eingabe
Public Class bug
Public Shared Function ExponentialMovingAverage(Values() As Double) As Double
Dim Weight, TotalWeight As Double
ExponentialMovingAverage = 0
Weight = 1
TotalWeight = 0
For Each Value In Values
ExponentialMovingAverage += Value*Weight
TotalWeight += Weight
Weight /= 1-2/(Values.Length+1)
Next
ExponentialMovingAverage /= TotalWeight
Return ExponentialMovingAverage
End Function
Public Shared Sub Main
Dim v As Double = 20.41985000000000000000
Console.WriteLine(_
ExponentialMovingAverage({77.474, 1.4018}).ToString("0.00000000000000000000") & " --> " & _
Math.Round(ExponentialMovingAverage({77.474, 1.4018}), 4) & vbCrLf & _
v.ToString("0.00000000000000000000") & " --> " & _
Math.Round(v, 4))
End Sub
End Class
Ausführen dieses Codes gibt die folgende Ausgabe (Kultur nl-NL):
20,41985000000000000000 --> 20,4199
20,41985000000000000000 --> 20,4198
mit diesem kurzen Stück Code, um einen einfachen gleitenden Durchschnitt Funktion enthält Das Problem ist reproduzierbar und am besten dargestellt Wir wundern uns, warum die Ausgabe für 2 scheinbar identische Anrufe zu Math.Round
unterschiedlich ist. Es sollte keine Genauigkeitsprobleme geben, da der verwendete Wert weniger Ziffern hat als der 15-16 digits, der in einen Double
Datentyp passen sollte.
Suche im Internet gibt hauptsächlich Antworten auf Rundungsprobleme mit MidpointRounding
, die nicht verwandt scheint.
Wir freuen uns auf jede Antwort.
Wenn ich testen, die über Ihre Funktion 'ExponentialMovingAverage' eine Leistung von 20,419850000000004 – OSKM
Sie produziert * * keine unterschiedlichen Ergebnisse aus den gleichen Eingang. 'Math.Round()' ist deterministisch. Sie haben unterschiedliche Ergebnisse von Eingaben, die * gleich aussehen *. Die zugrunde liegenden Floats befinden sich in Base 2. Ein Artefakt der Anzeige von Base 2-Nummern in Base 10 ist, dass gelegentlich unterschiedliche Zahlen gleich angezeigt werden. Es scheint, dass VB.net leider ein eingebautes 'frexp()' fehlt, das Sie leicht die zugrundeliegenden Bit-Muster untersuchen lässt, aber etwas wie dieses sollte leicht zu vb übersetzt werden, wenn Sie neugierig sind: http: // stackoverflow. com/q/389993/4996248 –