vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Top-Preis! AP-Access-Tools-CD Volume 1  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2018
 
zurück
Rubrik: Variablen/Strings · Array/ArrayList   |   VB-Versionen: VB200802.07.08
Verhalten der Array.Sort Methode beim IEEE-Sonderwert NaN

Einige Methoden der Array-Klasse beachten den IEEE-Sonderwert NaN nicht. Vorgeschaltetes Filtern ist erforderlich.

Autor:   Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  8.813 
ohne HomepageSystem:  Win2k, WinXP, Vista, Win7, Win8, Win10kein Beispielprojekt 

Die Klasse System.Array stellt die SHARED-Methode 'Sort' zur Verfügung.

Eine der Überladungen dieser Methode akzeptiert ein eindimensionales Array. Alle Elemente des Array werden (ansteigend) sortiert und zwar gemäß der Implementierung der ICOMPARABLE-Schnittstelle der einzelnen Elemente.

Jeder Vergleich eines gültigen Double-Wertes mit dem IEEE-Sonderwert 'Double.NaN' ergibt 'false'. (Kein gültiger Double-Wert gilt als größer, kleiner oder gleich NaN.)

Variable des Typs 'Double' lösen bei numerischen Operationen nie eine Ausnahme aus.

Daraus folgt:
Beim Sortieren eines eindimensionalen Arrays, dessen Elemente Single- oder Double-Werte sind, und das NaN-Werte enthält, stehen nach dem Sortiervorgang diese Werte 'irgendwo' im Array - zwischen den gültigen Werten. ('PositiveInfinities' stehen nach dem Sortieren im Array hinten, 'NegativeInfinities' stehen vorne. Das ist korrekt).

NaN-Werte, ihre Entstehung und ihre Auswirkungen sind in numerischen Anwendungen nicht zu unterschätzen. Sie bilden nicht nur das Resultat der Operation 0 / 0, sondern werden auch nach Durchführung vieler Operationen zurückgegeben, die zu einem 'undefinierten' Zustand führen. Das gilt z.B. für mathematische Funktionen in den Modulen 'System.Math' und 'Financial', für Methoden der BitConverter-Klasse, für die Compare-Methode, den Mod-Operator und den Ergebnissen von Datenbank-Abfragen. NaN-Werte passieren Konvertierungsfunktion (CDbl, CSng), aber auch Filter (IsNumeric) unbeanstandet.

Es empfiehlt sich deshalb, vor Verwendung der ‚Sort’-Methode einen NaN-Check des Array durchzuführen.

Die Ermittlung von NaN-Werten im sortierten Array durch die 'BinarySearch'-Methode ist nicht möglich. Aus den oben genannten Gründen wird gewöhnlich 'false' zurückgegeben.

Seit VB2008 sind 'Extension Methods' auch für numerische Arrays der Klasse System.Array verfügbar. Die Methoden 'Average', 'Sum', 'Max' und 'Min' kommen mit dem NaN-Wert teilweise nicht zurecht. 'Average' und 'Sum' geben aber gewöhnlich 'NaN' zurück, falls NaN-Werte im Array enthalten sind.

Hier einige Routinen (als 'Extension Methods'), die Sie jetzt vielleicht interessieren könnten.

Um diese Funktionen als Erweiterungsmethoden aufrufen zu können, müssen sie mit dem Schlüsselwort PUBLIC in einem Modul deklariert werden.

Die Routine 'Remove_NaN' entfernt alle NaN-Werte aus dem Array. Das Array wird ggf. verkürzt. Wenn keine Werte übrig bleiben, wird 'Nothing' zurückgegeben. Nach Durchführung der Routine kann das Array unbesorgt verwendet werden (Infinity-Werte sind ggf. noch drin!)

Die Routinen 'MinVal', 'MaxVal' und 'SumVal' rufen intern jeweils zunächst 'Remove_NaN’ auf. Die zurückgegebenen Werte beziehen sich deshalb nur auf die gültigen Array-Elemente. Falls es keine gültigen Elemente im Array gibt, wird Double.NaN zurückgegeben.

Die Routine 'SortVal' liefert ein sortiertes Array gültiger Werte, das ggf. verkürzt worden ist. Falls keine Werte zum Sortieren übrig bleiben, wird eine Ausnahme ausgelöst.

Hinweis für VB6-Umsteiger:
Wenn Sie sich jetzt wundern, liegen Sie richtig.
In VB6 lösen IEEE-Sonderwerte Ausnahmen aus und bieten so dem Programm die Möglichkeit zu reagieren. Das VB6-Verhalten entspricht einer 'SOLLTE'-Bedingung in den IEEE-Konventionen.

In den aktuellen Basic-Versionen ist nur die Funktion 'IsNaN' in der Lage, bei IEEE-Variablen die Ausnahmebedingung zu erkennen. Da sie bei häufigem Gebrauch ein Performance-Killer ist, wird sie VB-Intern anscheinend nicht oft eingesetzt. Es bleibt gewöhnlich dem Programmierer überlassen, wo er diesen Sonderwert abfragen und wie er ihn verarbeiten will.

''' <summary>
''' Entfernung aller Double.NaN-Werte
''' </summary>
''' <param name="arr">Array</param>
<System.Runtime.CompilerServices.Extension()> _
Public Sub Remove_NaN(ByRef arr() As Double)
  Dim z As Integer = -1
  Dim iarr(arr.Length - 1) As Double
  For i As Integer = 0 To arr.Length - 1
    If Not Double.IsNaN(arr(i)) Then
      z += 1
      iarr(z) = arr(i)
    End If
  Next i
  If z < 0 Then arr = Nothing : Exit Sub
  ReDim Preserve iarr(z)
  arr = CType(iarr.Clone, Double())
End Sub
''' <summary>
''' Maximalwert im Vektor, sonst NaN 
''' </summary>
''' <param name="arr">Array</param>
''' <returns>Größter Wert oder NaN</returns>
<System.Runtime.CompilerServices.Extension()> _
Public Function MaxVal(ByVal arr() As Double) As Double
  arr.Remove_NaN()
  If IsNothing(arr) Then Return Double.NaN
  Return arr.Max
End Function
''' <summary>
''' Minimalwert im Vektor, sonst NaN 
''' </summary>
''' <param name="arr">Array</param>
''' <returns>Kleinster Wert oder NaN</returns>
<System.Runtime.CompilerServices.Extension()> _
Public Function MinVal(ByVal arr() As Double) As Double
  arr.Remove_NaN()
  If IsNothing(arr) Then Return Double.NaN
  Return arr.Min
End Function
''' <summary>
''' Summe der Vektor-Elemente, sonst NaN 
''' </summary>
''' <param name="arr">Array</param>
''' <returns>Summe der Elemente oder NaN</returns>
<System.Runtime.CompilerServices.Extension()> _
Public Function SumVal(ByVal arr() As Double) As Double
  arr.Remove_NaN()
  If IsNothing(arr) Then Return Double.NaN
  Return arr.Sum
End Function
''' <summary>
''' Sortieren der Vektor-Elemente, sonst NaN 
''' </summary>
''' <param name="arr">Array</param>
<System.Runtime.CompilerServices.Extension()> _
Public Sub SortVal(ByRef arr() As Double)
  arr.Remove_NaN()
  If IsNothing(arr) Then
    Throw New ArgumentException
  End If
  Array.Sort(arr)
End Sub

Dieser Tipp wurde bereits 8.813 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Neue Diskussion eröffnen

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2018 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel