We're running into an issue with VB.NET's Math.Round
method where we're getting different results for the same input. The problem is reproducible and best illustrated using this short piece of code containing a simple moving average function:
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
Running this code gives the following output (culture nl-NL):
20,41985000000000000000 --> 20,4199
20,41985000000000000000 --> 20,4198
We're wondering why the output is different for 2 seemingly identical calls to Math.Round
. There should not be any precision problems as the value used has less digits than the 15-16 digits that should fit in a Double
data type.
Searching the web mainly returns answers to rounding problems having to do with MidpointRounding
, which seems unrelated.
Looking forward to any replies.