Zur Berechnung des natürlichen Logarithmus einer Zahl steht in Net-VB die Funktion "Log" (Namespace: System.Math) zur Verfügung. Sie akzeptiert als Argument Variable des Datentyps "Double" und berechnet den nat. Logarithmus mit einer Genauigkeit von etwa 14-15 Stellen. Eine höhere Genauigkeit (mind. 25 Stellen) lässt sich erzielen, wenn man auf den Datentyp "Decimal" zurückgreift und Logarithmen-Werte durch eine geeignete Reihenentwicklung approximiert (z.B. nach Napier). Für mich überraschend, arbeitet beim Datentyp "Decimal" der BKM-Algorithmus, der auf eine Logarithmentabelle zurückgreift, weniger effizient als das "klassische" Napier-Verfahren, das in vielen Fällen bereits nach der Berechnung von wenigen Termen den genauen Logarithmus liefert. Eine hohe Genauigkeit des Logarithmus lässt sich allerdings nur erzielen, wenn der Wert des Arguments im Datentyp "Decimal" exakt dargestellt werden kann. Bei Dezimalbrüchen kann es zu kleinen Ungenauigkeiten kommen, die die Präzision des Logarithmus um 1-3 Stellen herabsetzen. Kann der Dezimalbruch als gewöhnlicher Bruch dargestellt werden, ist die Berechnung der Differenz zwischen dem Zähler-Log und dem Nenner-Log genauer. Einschränkungen des Datentyps "Decimal" bei der Verarbeitung von kleinen Werten sind zu beachten: Anwendungsbeispiel für den natürlichen Logarithmus des Dezimalbruchs 2 / 3: Math.Log(2# / 3#) ' --> -0.40546510810816444# (15 Stellen) Math.Log(2#) - Math.Log(3#) --> -' 0.4054651081081645# (15 Stellen) LN_Napier(2D) - LN_Napier(3D) ' --> -0.4054651081081643819780131154D (28 Stellen) LN_Napier(2D / 3D) ' --> -0.4054651081081643819780131142D (26 Stellen) Anwendungsbeispiel für den natürlichen Logarithmus des Epsilonwertes 1.23456789E-25:
Dieser Wert ist als Decimal zwar noch darstellbar, aber nur als 0.0000000000000000000000001235D LN_Napier(CDec(1.23456789E-25#), True) ' --> -57.353556354771201581840486473D (5 Stellen !!) Als Double-Wert ist eine exakte Darstellung möglich: 1.23456789E-25 Math.Log(1.23456789E-25#) ' --> -57.353906302635487 (15 +1 Stellen) Der größte berechenbare natürliche Logarithmus: LN_Napier(Decimal.MaxValue) ' --> 66.542129333754749704054283602D (27 Stellen; über 100 Terme) ''' <summary>Logarithmus eines positiven Decimal-Wertes (n. Napier)</summary> ''' <param name="arg">Argument (größer 0)</param> ''' <param name="AcceptEpsilonArgs">Sollen Argument kleiner 0.00001 ''' akzeptiert werden</param> ''' <param name="steps">Zahl der erforderlichen Terme</param> ''' <returns>natürlicher Logarithmus des Arguments</returns> Public Function LN_Napier(ByVal arg As Decimal, _ Optional ByVal AcceptEpsilonArgs As Boolean = False, _ Optional ByRef steps As Integer = -1) As Decimal Const epsilon As Decimal = 0.0000000000000000000000000001D Const ln10 As Decimal = 2.3025850929940456840179914526D If arg <= 0D Then Throw New ArgumentOutOfRangeException("Logarithmus für negativen Wert undefiniert") End If If Not AcceptEpsilonArgs Then If arg < 0.00001 Then Throw New ArgumentException("Logarithmus: Wert nahe 0 ist nicht zugelassen") End If End If ' ggf. Transformation des Arguments (Bereich 1-10) Dim argkorr As Decimal = 0D While arg > 10 arg /= 10 : argkorr += 1 End While While arg < 1 arg *= 10 : argkorr -= 1 End While Dim helpfactor As Decimal = _ ((arg - 1D) * (arg - 1D)) / ((arg + 1D) * (arg + 1D)) ' Startwerte Dim log As Decimal = (arg - 1) / (arg + 1) Dim bruch As Decimal = log Dim add As Decimal, index As Decimal = 1D steps = 1 Do steps += 1 index += 2D bruch *= helpfactor add = bruch / index log += add Loop While Math.Abs(add) > epsilon Return (log * 2D) + argkorr * ln10 End Function ''' <summary>Logarithmus eines positiven Decimal-Wertes</summary> ''' <param name="arg">Argument (größer 0)</param> ''' <param name="base">Basis des Logarithmus (größer 0)</param> ''' <returns>Logarithmus des Arguments zur Basis</returns> Public Function Log_Napier(ByVal arg As Decimal, _ ByVal base As Decimal, _ Optional ByVal AcceptEpsilonValues As Boolean = False) As Decimal Return LN_Napier(arg, AcceptEpsilonValues) / _ LN_Napier(base, AcceptEpsilonValues) End Function Dieser Tipp wurde bereits 11.098 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. |
sevISDN 1.0 Überwachung aller eingehender Anrufe! Die DLL erkennt alle über die CAPI-Schnittstelle eingehenden Anrufe und teilt Ihnen sogar mit, aus welchem Ortsbereich der Anruf stammt. Weitere Highlights: Online-Rufident, Erkennung der Anrufbehandlung u.v.m. Tipp des Monats April 2024 Skyfloy Chart von Microsoft und dazu noch gratis Tutorial für Microsoft Chart Controls für Microsoft .NET Framework 3.5 Neu! sevPopUp 2.0 Dynamische Kontextmenüs! Erstellen Sie mit nur wenigen Zeilen Code Kontextmenüs dynamisch zur Laufzeit. Vordefinierte Styles (XP, Office, OfficeXP, Vista oder Windows 8) erleichtern die Anpassung an die eigenen Anwendung... |
||||||||||||||||
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. |