Feedback

VB - Berechnet den Durchschnittswert von grossen Zahlenlisten

Veröffentlicht von am 11/16/2009
(2 Bewertungen)
Calculation of average values of a infinite large list
Berechnet den Durchschnittswert einer Zahlenliste.

Beispiel:
Der Durchschnitt aus 3, 5 und 10 ist
(3 + 5 + 10 / 3 =
18 / 3 = 6

Was aber, wenn wir die Zahlen
98798798, 98127988479, 1000000 und weitere 1000 dieser Zahlen berechnen sollen und eine Summe das Maximum des Zahlentypes LONG überschreiten würde?

Diese Klasse bietet hier einfach Abhilfe. Sie kann auch gleich das Maximum einer Zahlenliste zurückliefern und die Liste nach Belieben auf eine vorgegebene Grösste stutzen.

Verwendet wird das ZB. in meiner Audio-FFT Darstellung:
http://www.goldengel.ch/audiocenter/tb-playlisthelper/
Die Frequenzamplitude kann per Mausklick in das Equalizerfeld, mit einer Durchschnittsberechnung angezeigt werden.

''' <summary>
''' Can calculate the maximum and average of the values.
''' This class will help to have some better informations of
''' data in small databases.
''' </summary>
''' <remarks></remarks>
Public Class clsTbQueue
    Private _LastMax As Single = 0


    Private _BufferSize As Integer
    ''' <summary>
    ''' The maximum of values for the content.
    ''' To activate the buffer the methode ".Trim" has to be used.
    ''' </summary>
    Public Property BufferSize() As Integer
        Get
            Return Me._BufferSize
        End Get
        Set(ByVal value As Integer)
            Me._BufferSize = value
        End Set
    End Property

    Private _Values As List(Of Single)
    ''' <summary>
    ''' The content of the values
    ''' </summary>
    Public Property Values() As List(Of Single)
        Get
            Return Me._Values
        End Get
        Set(ByVal value As List(Of Single))
            Me._Values = value
        End Set
    End Property


    ''' <summary>
    ''' Returns the maximum value in the list. Additional saves the current state to hold the maximum higher.
    ''' </summary>
    Public Function SlowMax() As Single
        Dim res As Single = 0
        Dim resMax As Single = Me.MaxValue

        If resMax >= Me._LastMax Then
            res = resMax
        Else
            res = (resMax / 10 * 1) + (Me._LastMax / 10 * 9)
        End If
        Me._LastMax = res
        Return res
    End Function


    ''' <summary>
    ''' Returns the maximum value in the list
    ''' </summary>
    Public Function MaxValue() As Single
        Dim res As Single = 0

        If Me._Values IsNot Nothing Then
            For i As Integer = 0 To Me._Values.Count - 1
                res = Math.Max(res, Me._Values(i))
            Next
        End If
        Return res
    End Function


    ''' <summary>
    ''' Returns the average value of the list. Large lists are supported.
    ''' </summary>
    Public Function Average() As Single
        Return Me.Average(Me._Values)
    End Function


    ''' <summary>
    ''' Returns the average value of the list. The list can be a large as you want.
    ''' Copyright by Timo Böhme 2009
    ''' </summary>
    Private Function Average(ByVal values As List(Of Single)) As Single
        Dim res As Single = 0

        Try
            If values Is Nothing OrElse values.Count = 0 Then Return res
            If values.Count = 1 Then Return values(0)

            res = values(0)
            For i As Integer = 2 To values.Count
                res = (res * ((i - 1) / i)) + (values(i - 1) * (1 / i))
            Next
        Catch ex As Exception

        End Try

        Return res
    End Function


    Public Sub Trim()
        If Me._Values Is Nothing Then Exit Sub
        If Me._BufferSize < 0 Then Exit Sub

        Do
            If Me._Values.Count < Me._BufferSize Then Exit Do
            Me._Values.RemoveAt(0)
        Loop
    End Sub

    Public Sub New()
        Me._Values = New List(Of Single)
        Me._BufferSize = -1
    End Sub

    Public Sub New(ByVal BufferSize As Integer)
        Call Me.New()
        Me._BufferSize = BufferSize
    End Sub
End Class

1 Kommentare zum Snippet

jack schrieb am 2/24/2010:
brilliant
 

Logge dich ein, um hier zu kommentieren!