Base_Convert() mit beliebig vielen Stellen

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Base_Convert() mit beliebig vielen Stellen

Beitrag von NicTheQuick »

Hallo Leute!

Jemand wollte PI im Zwölfersystem wissen, deshalb hab ich ein kleines
Progrämmchen geschrieben, dass das auch hinkriegt. Mit der folgenden
Funktion ist es möglich zwischen den Zahlensystemen von 2 bis 36 zu
konvertieren. Dabei müssen die Zahlen als String vorliegen.

///Edit:
Nachkommastellen müssen mit dem Punkt '.' abgetrennt werden.

Viel Spaß damit:

Code: Alles auswählen

Procedure.s Base_Convert(Value.s, InBase.l = 10, OutBase.l = 2, nbDecimals.l = 100)
  Protected p.l, *c.Character, left.s, l.l, lout.s, Mod.l, out.s, rout.s, right.s, a.l
  
  *c = @Value
  While *c\c
    Select *c\c
      Case '0' To '9' : *c\c - '0' + 1
      Case 'a' To 'z' : *c\c - 'a' + 11
      Case 'A' To 'Z' : *c\c - 'A' + 11
      Case '.' ;do nothing
      Default : *c\c = 1
    EndSelect
    *c + SizeOf(Character)
  Wend
  
  p = FindString(Value, ".", 1)
  If p
    left = Left(Value, p - 1)
    right = Mid(Value, p + 1, Len(Value) - p)
  Else
    p = Len(Value)
    left = Value
    right = ""
  EndIf
  
  If left ;Vorkommateil
    While left <> ""
      Mod = 0 : *c = @left : out = ""
      While *c\c
        Mod = Mod * InBase + *c\c - 1
        l = Mod / OutBase
        If l Or out
          out + Chr(l + 1)
        EndIf
        Mod - (l * OutBase)
        
        *c + SizeOf(Character)
      Wend
      
      left = out
      lout = Chr(Mod + 1) + lout
    Wend
  Else
    lout = Chr(1)
  EndIf
  
  If right ;Nachkommateil
    a = 0
    p = Len(right)
    While right <> Chr(1) And a < nbDecimals
      *c = @right + (p - 1) * SizeOf(Character)
      p = 0 : Mod = 0 : out = ""
      While *c >= @right
        Mod + (*c\c - 1) * OutBase
        out = Chr((Mod % InBase) + 1) + out
        Mod / InBase
        *c - SizeOf(Character)
        p + 1
      Wend
      
      right = out
      rout + Chr(Mod + 1)
      a + 1
    Wend
  EndIf
  
  If rout : out = lout + "." + rout : Else : out = lout : EndIf
  
  *c = @out
  While *c\c
    Select *c\c
      Case 1 To 10 : *c\c + '0' - 1
      Case 11 To 36 : *c\c + 'A' - 11
      Case '.' ;do nothing
      Default : *c\c = '?'
    EndSelect
    *c + SizeOf(Character)
  Wend
  
  ProcedureReturn out
EndProcedure

Define s.s
Debug "Beispiel für 10 -> 2 und zurück"
s = Base_Convert("3.1415926535897932384626433832795028841971693993", 10, 2, 100)
Debug s
Debug Base_Convert(s, 2, 10, 100)
Debug "3.1415926535897932384626433832795028841971693993 (Original)"
Debug "Beispiel für 10 -> 36 und zurück"
s = Base_Convert("3.1415926535897932384626433832795028841971693993", 10, 36, 100)
Debug s
Debug Base_Convert(s, 36, 10, 100)
Debug "3.1415926535897932384626433832795028841971693993 (Original)"