NSC - Zahlensysteme umrechnen von einer Basis in ein Anderes

    • VB.NET
    • .NET (FX) 4.0

      NSC - Zahlensysteme umrechnen von einer Basis in ein Anderes

      Aller Anfang zwei Bilder



      Hinweis: Umrechnungen wie z.B. Basis 2 zu Basis 16.
      Wie man auf dem Bild erkennen kann, können die entsprechenden Werte schon im ersten Schritt, in der ersten Zeile abgeleitet werden. Das erhöht die Performance für die Berechnung um ein vielfaches.



      Der Algorithmus

      Die binäre Zahl 10101010010100110111010 soll in eine Zahl mit Basis 10 umgerechnet werden.

      Damit eine solche Berechnung gemacht werden kann, benötigt der Algorithmus dazu 2 Schritte und zwei verschiedene Formeln. Beide Schritte werden in der Schleife immer und immer wieder abgearbeitet, bis die Zahlenreihe des zweiten Schrittes durchgehend 0 ist.

      Der erste Schritt liefert pro Position ein Zwischenergebnis, der parallel für den zweiten Schritt benötigt wird.
      Der letzte Wert der Zahlenreihe ist die gesuchte Zahl der neuen Basis. Der Anfangswert dieser Zahlenreihe ist bei jedem Durchgang immer 0. Der erste Schritt kann im Programm als Zwischenschritt angeschaut werden.

      Der zweite Schritt liefert alle Zahlen die als Grundlage wieder für diese zwei Schritte verwendet wird.


      Zwei Formeln (Manuelles Verfahren)

      Manuell gerechnet, wird nur eine Variable r benötigt. Als Programm sind jedoch zwei Variablen nötig r, rT. Nach jedem Durchgang der ganzen Zahlenreihe (von links nach rechts), wird r wieder auf 0 gesetzt. Genauso auch im Programm.

      Um es verständlicher zu machen, habe ich die Formeln zwei mal hingeschrieben. Einmal speziell für die 1. Position und einmal für die anderen Postionen der Zahlenreihe. Ab der 2. Position wird im manuellen Verfahren das Ergebnis des ersten Schritten an r übergeben. Der Wert von r hinkt also immer um eine Position hinterher. Die Variable BIT ist jener Wert der Zahlenreihenposition mit der als Grundlage gerechnet wird. (Nach jedem Durchgang der Schleife immer der zweite Schritt).

      rT = 0; r = 0; Die Anfangswerte für die erste Position der Zahlenreihe ist 0.

      Quellcode

      1. rT0 = ((startBase * r) + BIT) mod targetBase; Zwischenschritt
      2. r0 = ((startBase * r) + BIT) div targetBase;


      Ab der zweiten Position der ersten und zweiten Zahlenreihe

      Quellcode

      1. rTx = ((startBase * rx-1) + BIT) mod targetBase; Zwischenschritt
      2. rx = ((startBase * rx-1) + BIT) div targetBase;



      Der Code

      Die Klasse NSC - Numeral System Converter enthält den Algorithmus für die Umrechnung der Zahlensysteme. Sie konvertiert natürliche Zahlen (exkl. 0) gesplittet in einer Integer-Array von einer Basis ins Andere. Für negative Zahlen habe ich das Programm noch nicht getestet.

      Der Funktionsaufruf des Konverters benötigt 3 Variable. Die Integer-Array input als Abbild jener Zahl die umgerechnet werden soll, die Startbasis = 2 und die Zielbasis = 10 wie im Beispiel oben.

      VB.NET-Quellcode

      1. Public Function convert(ByVal input() As Integer, ByVal startBase As Integer, ByVal targetBase As Integer) As Integer()
      2. '..... Code .....
      3. End Function


      Alle Einstiegswerte werden zuerst geprüft, wobei CheckEmptyLess0() eine Funktion ist, die prüft, ob die Array input nur aus Nullen besteht oder negative Zahlen enthält.

      VB.NET-Quellcode

      1. If (input.Length > 0) AndAlso (Not CheckEmptyLess0(input)) AndAlso (startBase > 1) AndAlso (targetBase > 1) Then
      2. '..... Code .....
      3. End If


      Die Schleife mit der Umsetzung der oben erwähnten zwei Schritte.

      VB.NET-Quellcode

      1. 'Die For-Schleife iteriert durch die ganze Integer-Array.
      2. 'Zwei Schritte werden gemacht:
      3. 'Erster Schritt: rT berechnen nach der entsprechenden Formel (Zwischenschritt)
      4. 'Zweiter Schritt: den neuen Wert ausrechnen nach entsprechender Formel
      5. 'rT wird an r übergeben, damit das Zwischenergebnis immer um i-1 zurückhinkt, sobald die
      6. 'For-Schleife wieder von vorne anfängt.
      7. 'Zum Schluss eine kleine Prüfung, ob der neue Wert in ipt(i) grösser 0 ist.
      8. '>>> Sollte durchgehen 0 vorhanden sein wird 'ext' nie auf false umgeschaltet und somit
      9. '>>> wird die while-Schleife am Schluss verlassen.
      10. 'In der Whileschleife werden r (auf 0) und ext (zu True) immer wieder zurückgesetzt
      11. '- Der errechnete Endwert wird in der ListOfT festgehalten
      12. '- ext wird geprüft ob True. Wenn Wahr/True wird die Schleife verlassen
      13. While (True)
      14. r = 0 : ext = True
      15. For i As Integer = 0 To ipt.Length - 1
      16. rT = ((startBase * r) + ipt(i)) Mod targetBase
      17. ipt(i) = ((startBase * r) + ipt(i)) \ targetBase
      18. r = rT
      19. If ipt(i) > 0 Then ext = False
      20. Next
      21. lst.Insert(0, r)
      22. If ext Then Exit While
      23. End While


      Und zu guter Letzt die Mainfunktion

      VB.NET-Quellcode

      1. Public Sub Main()
      2. 'Instanzieren der benötigten Klassen
      3. 'NSC ist der Numeral System Converter
      4. 'Random1000 ist eine Klasse um den Anfangswert in der gewünschten Startbasis zu erhalten
      5. 'Stopwatch ist eine .Net-Klasse und wird benötigt, um die Zeit zu messen.
      6. Dim n As New NSC
      7. Dim r As New Random1000
      8. Dim sw As New Stopwatch
      9. 'Start- und Zielbasis bekannt geben
      10. Dim startBase As Integer = 10
      11. Dim targetBase As Integer = 5
      12. 'Zufälliger Anfangswert (Array) anfordern
      13. Dim iNum() As Integer = r.NewRnd1000(startBase)
      14. 'Prüfen ob erhaltener Anfangswert gültig ist.
      15. If iNum IsNot Nothing Then
      16. 'Zeitmessung einleiten.
      17. sw.Start()
      18. 'Berechnung durchführen
      19. Dim res() As Integer = n.convert(iNum, startBase, targetBase)
      20. 'Zeitmessung stoppen
      21. sw.Stop()
      22. 'Prüfen ob der erhalte Zielwert gültig ist.
      23. If res IsNot Nothing Then
      24. 'Aus dem Anfangswert einen String machen.
      25. Dim sNum As String = MakeStringNum(iNum, False)
      26. 'Aus dem Zielwert einen String machen.
      27. Dim sRes As String = MakeStringNum(res, False)
      28. 'Auf der Konsole ausgeben.
      29. PrintOut(sNum, sRes, startBase, targetBase, iNum.Length, res.Length, sw)
      30. End If
      31. End If
      32. 'Konsole anzeigen
      33. Console.ReadKey()
      34. End Sub



      BuchstabenSubstitutionen

      NSC - Numeral System Converter ist ein rein numerisches Lösungsverfahren. Sie kann jedoch problemlos erweitert werden. Z.B. mit einer Funktion für die Umwandlung der Integer-Array zu Hex-Werten als String. Das könnte man in etwa so bewerkstelligen.

      VB.NET-Quellcode

      1. Private literals As String = "0123456789ABCDEF"
      2. Private Function HexLiteralSubstitution(ByVal iArrB16() As Integer) As String
      3. If iArrB16.Length > 0 Then
      4. Dim sb As New StringBuilder(iArrB16.Length)
      5. For Each i As Integer In iArrB16
      6. sb.Append(literals(i))
      7. Next
      8. Return sb.ToString
      9. End If
      10. Return String.Empty
      11. End Function


      Auf die anderen Klassen und Funktionen möchte ich hier nicht eingehen. Sie sind im TestProjekt ausführlich kommentiert.


      Zusammenfassung

      NSC - Numeral System Converter ist ein Algorithmus, der Natürliche Zahlen im Integerbereich numerisch von einer Basis in eine andere Basis umrechnet. Die Umsetzung erfolgt in zwei Schritten mit sehr einfachen Formeln. NSC hat eine sehr gute Performance, und ist für Zahlenwerte mit mehreren 1000 Zifferstellen konzipiert, und kann quasi beliebig erweitert werden. Zahlenbasen von über 1Mio können problemlos berechnet werden.

      Viel Spass mit dem Programm.

      Freundliche Grüsse

      exc-jdbi
      Dateien

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „exc-jdbi“ ()