Die POW-Funktion in der Math-Klasse von VB.Net berechnet die Potenz einer Zahl. Der erste Funktionsparameter (x) enthält die Zahl, die potenziert werden soll (mathematisch: Basis oder Grundzahl), der zweite Parameter (y) enthält den Exponenten (mathematisch auch: Hochzahl). Die Funktion akzeptiert IEEE-Sonderwerte in den Parametern und verarbeitet die Werte nachdem 16 (+1) Fallunterscheidungen berücksichtigt worden sind. Im Funktions-Ergebnis kann ein Double-Wert oder einer der IEEE-Sonderwerte auftreten. Ausnahmen werden von Math.Pow nicht ausgelöst. Ebensowenig erfährt man, welcher der 16 (+1) Fälle bei der Bearbeitung aufgetreten ist, oder ob es zu einem Überlauf der Gleitkomma-Arithmetik bei Ermittlung der Potenz gekommen ist. Aufgrund dieses überaus flexiblen und liberalen Verhaltens, ist bei der Verwendung der POW-Funktion einige Vorsicht geboten. Es ist nämlich in den meisten VB-Programmen sorgfältig zu unterscheiden,
Die Überprüfung des Funktionsergebnisses liefert meist nicht die benötigte eindeutige Information für eine geeignete Verzweigung im weiteren Programmablauf. Ein 'Nan'-Wert im Ergebnis kann auf einen Nan.-Wert in den Parameter, auf mathematische Unzulässigkeit der Berechnung oder auf Anwendung der Unendlichkeitsarithmetik zurückführbar sein. Ein Infinity-Wert im Ergebnis kann auf Anwendung der Unendlichkeits-Arithmetik oder auf einen Überlauf der Gleitkomma-Darstellung des Ergebnisses zurückführbar sein. Aber auch die Zahlen-Werte 0.0 bzw. 1.0 können als Ergebnis der Unendlichkeits-Arithmetik auftreten. Bei genauerer Betrachtung erweist sich die POW-Funktion in der Anwendung also als ein recht verzwickt zu handhabendes Werkzeug. Übersicht über die Unendlichkeits-Arithmetik der POW-Funktion: Enthält die Basis (x-Parameter) den Wert -unendlich, wird das POW-Resultat ...
Enthält die Basis (x-Parameter) den Wert +unendlich, wird das POW-Resultat ...
Enthält der Exponent (y-Parameter) den Wert -unendlich, wird das POW-Resultat ...
Enthält der Exponent (y-Parameter) den Wert +unendlich, wird das POW-Resultat ...
Es werden nicht nur Infinity-Werte in der Eingabe, sondern auch Grenzübergänge bei der Infinity-Arithmetik berücksichtigt:
Zusätzlich ist zu beachten, dass ein Überlauf der Gleitkomma-Arithmetik ebenfalls +/-unendlich im Ergebnis liefert. Insbesondere die Unendlichkeits-Bedingungen, unter denen POW die Werte 0 bzw. 1 zurückgibt, sind heikel, weil sie in komplexen mathematischen Termen verschleiern können, dass Infinity-Werte bei Zwischenergebnissen aufgetreten sind (und deshalb die Unendlichkeits-Arithmetik zur Anwendung kam). Bedingungen, unter denen die POW-Funktion ein undefiniertes Ergebnis ('NaN') liefert:
Um die POW-Funktion bei eigenen Anwendungen in geeigneter Weise in einer Funktion zu kapseln, sind verschiedenartige Lösungen denkbar - abhängig davon, ob man die Unendlichkeits-Werte ganz oder teilweise akzeptiert und ob die Overflow-Bedingung abgefangen werden soll. Die kapselnde Funktion 'POWER1' ist im Hinblick auf die Ausnahmen besonders restriktiv. Sie erlaubt keine IEEE-Sonderwerte in den Eingabeparametern und in der Ergebnis-Rückgabe vom POW. Die kapselnde Funktion 'POWER2' duldet die Unendlichkeitsarithmetik weitgehend und löst eine Ausnahme nur aus, wenn 'undefinierte' Werte in den Parametern oder im Funktionsergebnis auftreten. Die kapselnde Funktion 'POWER3' löst beim Auftreten von Sonderfällen, wie sie die VB-Dokumentation auflistet, Ausnahmen aus, meldet aber im Error-Objekt, welche Bedingung die Ausnahme verursacht hat. Im CATCH-Block des aufgefangenen Fehlers können dann für die einzelnen Sonderfälle geeignete Verzweigungen vorgenommen werden. Der optionale Parameter 'Check_Result' entscheidet darüber, ob zusätzlich noch Gleitkomma-Überläufe im Funktions-Ergebnis von POW eine Ausnahme auslösen sollen. 'POWER3' löst nicht bei allen Sonderfällen Ausnahmen aus, sondern nur bei denen, die im POW-Ergebnis zu einem IEEE-Sonderwert führen. Unter bestimmten Bedingungen werden Infinity-Werte in den Parametern toleriert - vgl oben.. Die kapselnde Funktion 'POWER4' verzichtet völlig auf Ausnahmen und meldet statt dessen im optionalen SHORT-Rückgabeparameter 'Fall' ggf. welcher der 16 Fälle, die die POW-Funktion unterscheidet, vorliegt. Falls das Ergebnis nicht auf einem Sonderfall beruht, aber den Min-Max-Bereich von DOUBLE überschreitet, wird der Fall -1 gemeldet, sonst 0. Public Function Power1(ByVal basis As Double, _ ByVal exponent As Double) As Double ' Die Funktion löst stets einen Fehler aus, ' wenn in einem Argument oder im POW-Ergebnis ' ein IEEE-Sonderwert auftritt If Not Im_Double_Bereich(basis) Then Throw New Exception("Basis nicht im Double-Bereich") ElseIf Not Im_Double_Bereich(exponent) Then Throw New Exception("Exponent nicht im Double-Bereich") End If Dim Resultat As Double = Math.Pow(basis, exponent) If Not Im_Double_Bereich(Resultat) Then Throw New Exception("Resultat nicht im Double-Bereich") End If Return Resultat End Function Public Function Power2(ByVal basis As Double, _ ByVal exponent As Double) As Double ' Die Funktion löst stets einen Fehler aus, ' wenn in einem Argument oder im POW-Ergebnis ' der IEEE-Sonderwert 'NaN' auftritt Dim Resultat As Double = Math.Pow(basis, exponent) If Double.IsNaN(Resultat) Then Throw New Exception("POW-Funktion: Not a Number") End If Return Resultat End Function Public Function Power3(ByVal basis As Double, _ ByVal exponent As Double, _ Optional ByVal Check_Result As Boolean = True) As Double ' Die Funktion kapselt die MATH.POW-Funktion ' und löst bei Parameter-Bedingungen, die zu ' IEEE-Sonderwerten in der Rückgabe führen würden, ' einen auffangbaren Fehler aus ' Die als Kommentar angegebenen Fallnummern beziehen ' sich auf die Reihenfolge der Bedingungen in der Liste, ' die in der VB-Doku zur MATH.POW-Methode enthalten ist ' Check_Result entscheidet darüber, ob ermittelt wird, ' ob das POW-Ergebnis als Double-Wert darstellbar ist ' (--> Gleitkomma-Überlauf abfangen) Dim m As String = "" Dim erg As Double ' Ergebnis von POW ' Hilfswertre für +/-Unendlich im Exponenten Dim ExpoNegInf As Boolean = Double.IsNegativeInfinity(exponent) Dim ExpoPosInf As Boolean = Double.IsPositiveInfinity(exponent) Dim BasisNegInf As Boolean = Double.IsNegativeInfinity(basis) ' Fall 1 If Double.IsNaN(basis) Then Throw New Exception("POW: Basis ist keine Zahl") End If If Double.IsNaN(exponent) Then Throw New Exception("POW: Exponent ist keine Zahl") End If ' Fall 4/5 If BasisNegInf Then If exponent > 0 Then Throw New Exception("POW: Basis = -unendlich, Exponent > 0") End If End If ' Fall 6/7 If basis < 0 Then If basis < -1 And ExpoNegInf Then ' OK: hier kommt im Ergebnis 0 (Fall 10) ElseIf ExpoNegInf Then Throw New Exception("POW: Basis < 0, Exponent -unendlich") ElseIf ExpoPosInf Then If basis > -1 Then ' OK: hier kommt im Ergebnis 0 (Fall 9) Else Throw New Exception("POW: Basis < 0, Exponent +unendlich") End If End If If Not BasisNegInf Then If exponent <> Fix(exponent) Then Throw New Exception("POW: Basis < 0, Exponent nicht ganzzahlig") End If End If End If If basis > -1 And basis < 1 Then ' Fall 8 If ExpoNegInf Then Throw New Exception("POW: -1 < Basis < 1, Exponent -unendlich") End If ElseIf basis < -1 Or basis > 1 Then ' Fall 11 If basis < -1 Then m = "POW: Basis < -1" If basis > 1 Then m = "POW: Basis > 1" If ExpoPosInf Then Throw New Exception(m + " , Exponent +unendlich") End If End If ' Fall 12 If basis = 0 And exponent < 0 Then Throw New Exception("Basis = 0, Exponent < 0") End If ' Fall 16 If Double.IsPositiveInfinity(basis) Then If exponent > 0 Then Throw New Exception("Basis = +unendlich, Exponent > 0") End If End If ' Aufruf der POW-Funktion erg = Math.Pow(basis, exponent) If Check_Result Then ' zusätzliche Ausnahme, falls Überlauf der ' Gleitkomma-Arithmetik im Datentyp DOUBLE ' bei Zuweisung des Ergebnisses auftritt If Not Im_Double_Bereich(erg) Then Throw New Exception("POW: Ergebnis nicht in DOUBLE-Spannweite") End If End If Return erg End Function Public Function Power4(ByVal Basis As Double, _ ByVal Exponent As Double, _ Optional ByRef Fall As Short = -1) As Double ' Die Funktion ermittelt im opt. Parameter 'Fall' ' welcher Fall der VB-Doku-Liste bei Anwendung von POW ' vorliegt: ' Fall = 0 keine IEEE-Sonderwerte ' Fall = 1 bis 16 Nummer des Sonderfalls ' Fall = -1 Ergebnis nicht als Double darstellbar ' Fall = -2 nicht beabsichtigt Dim erg As Double ' POW-Rückgabe Dim ierg As Double ' intern: erwartete Rückgabe im Sonderfall ' Hilfswerte 'Infinity'-Parameter Dim BasisNegInf As Boolean = Double.IsNegativeInfinity(Basis) Dim BasisPosInf As Boolean = Double.IsPositiveInfinity(Basis) Dim ExpoNegInf As Boolean = Double.IsNegativeInfinity(Exponent) Dim ExpoPosInf As Boolean = Double.IsPositiveInfinity(Exponent) ' Rückgabe initialisieren Fall = -1 ' Sonderfälle ermitteln und ggf. notieren If Double.IsNaN(Basis) Or Double.IsNaN(Exponent) Then Fall = 1 : ierg = Double.NaN ElseIf Basis = 1 Then Fall = 14 : ierg = 1 ElseIf Basis = 0 Then If Exponent < 0 Then Fall = 12 : ierg = Double.PositiveInfinity ElseIf Exponent > 0 Then Fall = 13 : ierg = 0 End If ElseIf Exponent = 0 Then Fall = 2 : ierg = 1 ElseIf BasisNegInf Then If Exponent < 0 Then Fall = 3 : ierg = 0 ElseIf Exponent > 0 Then If Exponent - Fix(Exponent) = 0 And Exponent Mod 2 <> 0 Then ' ganzzahlig, positiv, ungerade Fall = 4 : ierg = Double.NegativeInfinity Else Fall = 5 : ierg = Double.PositiveInfinity End If End If ElseIf BasisPosInf Then If Exponent < 0 Then Fall = 15 : ierg = 0 ' 0 ElseIf Exponent > 0 Then Fall = 16 : ierg = Double.PositiveInfinity End If ElseIf Basis = -1 Then If ExpoPosInf Or ExpoNegInf Then Fall = 7 : ierg = Double.NaN End If ElseIf Basis > -1 And Basis < 1 Then If ExpoNegInf Then Fall = 8 : ierg = Double.PositiveInfinity ElseIf ExpoPosInf Then Fall = 9 : ierg = 0 End If ElseIf Basis < -1 Or Basis > 1 Then If ExpoNegInf Then Fall = 10 : ierg = 0 ElseIf ExpoPosInf Then Fall = 11 : ierg = Double.PositiveInfinity End If End If If Basis < 0 And Fall = -1 Then If ExpoNegInf Or ExpoPosInf Or Exponent <> Fix(Exponent) Then Fall = 6 : ierg = Double.NaN End If End If ' POW ausführen erg = Math.Pow(Basis, Exponent) If Fall = -1 Then ' Ergebnis im DOUBLE-Wertebereich? (--> Fall 0) If Im_Double_Bereich(erg) Then Fall = 0 Else ' Bei Sonderfall: ' Erwartete Rückgabe = tatsächliche Pow-Rückgabe ?? If Not Double_Vergleich(erg, ierg) Then Fall = -2 'Diese Bedingung sollte nicht auftreten End If End If ' POW-Ergebnis zurückgeben Return erg End Function Public Function Im_Double_Bereich( _ ByVal x As Double) As Boolean ' Hilfsfunktion: Prüfung der Double-Spannweite If x >= Double.MinValue And x <= Double.MaxValue Then Return True Else ' IEEE-Sonderwert (Infinity, NaN) Return False End If End Function Public Function Double_Vergleich( _ ByVal x As Double, ByVal y As Double) As Boolean ' Die Funktion prüft, ob der Inhalt von ' zwei Double-Variablen identisch ist If Double.IsNaN(x) And Double.IsNaN(y) Then Return True ElseIf x = y Then Return True Else Return False End If End Function Dieser Tipp wurde bereits 14.689 mal aufgerufen. Voriger Tipp | Zufälliger Tipp | Nächster Tipp
Anzeige
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. |
Neu! sevEingabe 3.0 Einfach stark! Ein einziges Eingabe-Control für alle benötigten Eingabetypen und -formate, inkl. Kalender-, Taschenrechner und Floskelfunktion, mehrspaltige ComboBox mit DB-Anbindung, ImageComboBox u.v.m. Tipp des Monats März 2024 Dieter Otter UTF-8 Konvertierung von Dateien und Strings VB6 selbst verfügt über keine Funktionen zur UTF-8 Konvertierung von Daten. Mit Hilfe des ADODB.Stream-Objekts lassen sich diese fehlenden Funktionen aber schnell nachrüsten. Access-Tools Vol.1 Über 400 MByte Inhalt Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB |
||||||||||||||||
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. |