Kami mengalami masalah dengan metode Math.Round
VB.NET di mana kami mendapatkan hasil yang berbeda untuk masukan yang sama. Masalahnya dapat direproduksi dan diilustrasikan dengan baik menggunakan potongan kode singkat yang berisi fungsi rata-rata bergerak sederhana:
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
Menjalankan kode ini akan menghasilkan output berikut (culture nl-NL):
20,41985000000000000000 --> 20,4199
20,41985000000000000000 --> 20,4198
Kami bertanya-tanya mengapa keluarannya berbeda untuk 2 panggilan yang tampaknya identik ke Math.Round
. Seharusnya tidak ada masalah presisi karena nilai yang digunakan memiliki digit lebih sedikit daripada 15-16 digit yang sesuai dengan tipe data Double
.
Penelusuran di web terutama menghasilkan jawaban atas masalah pembulatan yang berkaitan dengan MidpointRounding
, yang tampaknya tidak ada hubungannya.
Menantikan balasan apa pun.
ExponentialMovingAverage
menghasilkan output 20.419850000000004 - person OSKM   schedule 10.04.2017Math.Round()
bersifat deterministik. Anda mendapatkan hasil berbeda dari masukan yang terlihat sama. Float yang mendasarinya berada di basis 2. Artefak menampilkan angka basis 2 di basis 10 adalah terkadang angka yang berbeda menampilkan angka yang sama. Tampaknya VB.net sayangnya tidak memilikifrexp()
bawaan yang memungkinkan Anda dengan mudah memeriksa pola bit yang mendasarinya, tetapi hal seperti ini seharusnya mudah diterjemahkan ke vb jika Anda penasaran: stackoverflow.com/q/389993/4996248 - person John Coleman   schedule 10.04.2017