vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Erstellen von dynamischen Kontextmen?s - wann immer Sie sie brauchen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: Variablen/Strings · Algorithmen/Mathematik   |   VB-Versionen: VB2005, VB200829.12.09
Logarithmus mit hoher Genauigkeit

Auf der Basis des Datentyps Decimal kann das Napier-Verfahren Logarithmen mit einer Genauigkeit von 25 Stellen berechnen

Autor:   Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  11.063 
ohne HomepageSystem:  Win2k, WinXP, Win7, Win8, Win10, Win11kein Beispielprojekt 

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:
Decimal-Variable kennen keine Exponentialdarstellung. Der kleinste darstellbare Decimal-Wert größer 0 beträgt etwa 1E-28. Logarithmen für Werte, die nur wenig über 0 liegen (z.B. Epsilon-Werte bei Vergleichsoperationen), können deshalb durch die Funktion "LN_Napier" evt. nicht präzise bestimmt werden. Erst bei Argumenten ab 0.00001 ist eine auf etwa 25 Stellen präzise Abbildung gewährleistet. Der optionale Parameter "AcceptEpsilonArgs" gibt an, ob "LN_Napier" Argumente nahe 0 akzeptieren soll. Die VB-Funktion "Math.Log" liefert bei vielstelligen Double-Argumenten kleiner +1E-13 genauere (Double-) Ergebnisse als "LN_Napier" (wg. der Zahl der erforderlichen Nachkomma-Nullen).

Anwendungsbeispiel für den natürlichen Logarithmus des Dezimalbruchs 2 / 3:
("Exakter" Wert: -0,4054651081081643819780131154643491365719904 ....)

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:
("Exakter" Wert: -57,3539063026354895393997846566208146411226672837 ....)

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.063 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-2024 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