VB.NETのMath.Round
メソッドの問題が発生しており、同じ入力に対して異なる結果が得られています。問題は再現可能であり、最高の単純移動平均関数を含むコードのこの短い断片を使用して説明:VB.net Math.Round丸め問題 - 同じ入力に対して異なる結果が発生する
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
このコードを実行すると、次の出力が得られる(培養NL-NL):
20,41985000000000000000 --> 20,4199
20,41985000000000000000 --> 20,4198
私たちは、2つの一見同じ電話Math.Round
のために出力が異なっているのだろうと思っています。使用される値が、Double
データ型に収まる15-16 digitsよりも小さい桁数を持つため、精度上の問題はありません。
ウェブ検索では、主に無関係と思われる丸め問題の回答がMidpointRounding
と返されます。
返信をお待ちしております。
私はあなたの機能の上に 'ExponentialMovingAverage'が20.419850000000004 – OSKM
の出力を生成し、テストのRef MidPointRounding docsあなた* *同じ入力から異なる結果を持っていません。 'Math.Round()'は決定的です。あなたは同じ*見ている入力とは異なる結果を持っています。基礎となる浮動小数点数は、基数2になっています。基数10の基数2の数字を表示する人工物は、時々異なる数値が同じものを表示することがあります。残念ながら、VB.netには、基本的なビットパターンを簡単に検査できる組み込みの 'frexp()'が不足しているようですが、好きな場合はvbに簡単に変換できるはずです:http:// stackoverflow。 co.jp/q/389993/4996248 –