MultiConvert - Zahlensysteme in andere umrechnen

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.
Kristel
Beiträge: 72
Registriert: 30.08.2004 00:17

MultiConvert - Zahlensysteme in andere umrechnen

Beitrag von Kristel »

Will heute auch mal etwas für unsere Gemeinschaft tun.
Der ursprüngliche Code stammt von Rob.
Habe aber die Parameterprüfung und den Speed so verbessert,
dass die es sich eigentlich lohnt ihn hier so posten.
Vielleicht braucht den Code ja jemand.
Was macht der Code..
Er konvertiert jede Stringzahl mit einer Basis zwischen 2 und 36
in eine Stringzahl mit einer anderen Basis(2 bis 36). Wenn die Zahl
Zeichen enthält die die Basis nicht erlaubt oder eine zugroße/zukleine
Basis übergeben wird, gibt die Procedure -1 zurück. Daher sollte man
den Rückgabewert vorher prüfen, wie ich es weiter unten getan habe.

Code: Alles auswählen

Procedure.s MultiConvert(Zahl.s,in_basis.l,out_basis.l) ;kovertiert jede Stringzahl in ein anderes Zahlensystem
  Protected l.l, ziffer.s, i.l, ziffer_l.l, dec.l, ASC_Wert.l, ergebnis.s, rest.l, rest_s.s
  Zahl = UCase(Trim(Zahl))
  l = Len(Zahl)
  ;Prüfen ob die Zahlensystembereiche eingehalten wurden und ob, ein String übergeben wurde
  If l > 0 And 1 < in_basis And in_basis < 37 And 1 < out_basis And out_basis < 37
    ;Prüfung ob die Zeichen in der angegeben Basis erlaubt sind und wenn ja werden sie im
    ;Dezimalsystem ausgegeben und addiert 
    If in_basis < 11 
      For i = 0 To l-1
        ziffer = Mid(Zahl, l-i,1)
        If 47 < Asc(ziffer) And Asc(ziffer) < 58
          dec + Val(ziffer) * Pow(in_basis,i)
        Else
          ProcedureReturn "-1"
        EndIf
      Next
    Else 
      For i = 0 To l-1
        ziffer = Mid(Zahl, l-i,1)
        ASC_Wert = Asc(ziffer)
        If 47 < ASC_Wert And ASC_Wert < 58
          dec + Val(ziffer) * Pow(in_basis,i)
        ElseIf 64 < ASC_Wert And ASC_Wert < 91
          dec + (ASC_Wert-55) * Pow(in_basis,i)
        Else  
          ProcedureReturn "-1"
        EndIf
      Next
    EndIf
    ;wenn Ausgabebasis 10 ist muss nicht mehr gerechnet werden, denn
    ;die Zahl wird ja immer zuerst ins Dezimalsystem umgerechnet
    If out_basis = 10 
      ergebnis = Str(dec)
    Else ;ansonsten muss die Zahl berechnet werden
      Repeat
        rest = dec % out_basis
        dec / out_basis
        If rest > 9
          rest_s = Chr(55 + rest)
        Else
          rest_s = Str(rest)
        EndIf 
        ergebnis + rest_s
      Until dec = 0
    EndIf
    ProcedureReturn ergebnis ;die Zahl wird an das Hauptprogramm zurückgegeben
  EndIf  
  ProcedureReturn "-1"
EndProcedure

Zahl.s = "ff" ;die Zahl muss zur Basis passen sonst gibt die Procedure -1 zurück
in_basis.l = 16 ;in_basis und out_basis müssen größer als 1
out_basis.l = 10 ;und kleiner als 37 sein

Zahl = MultiConvert(Zahl,in_basis,out_basis)
If Zahl <> "-1"
  Debug Zahl
EndIf
End
Für Wünsche(falls ich noch was in der Richtung proggen soll), Anregungen und konstruktive Kritik bin ich immer offen.
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Ich glaub so is das ein bisl schneller:

Code: Alles auswählen

Procedure.s MultiConvert(Zahl.s,in_basis.l,out_basis.l) ;kovertiert jede Stringzahl in ein anderes Zahlensystem 
  Protected l.l, ziffer.s, i.l, ziffer_l.l, dec.l, ASC_Wert.l, ergebnis.s, rest.l, rest_s.s, *ziffer_p.BYTE
  Zahl = UCase(Trim(Zahl)) 
  l = Len(Zahl) 
  ;Prüfen ob die Zahlensystembereiche eingehalten wurden und ob, ein String übergeben wurde 
  If l > 0 And 1 < in_basis And in_basis < 37 And 1 < out_basis And out_basis < 37 
    ;Prüfung ob die Zeichen in der angegeben Basis erlaubt sind und wenn ja werden sie im 
    ;Dezimalsystem ausgegeben und addiert 
    If in_basis < 11 
      i = 0
      For *ziffer_p = @Zahl+l-1 To @Zahl Step -1
        If 47 < *ziffer_p\b And *ziffer_p\b < 58 
          dec + (*ziffer_p\b-48) * Pow(in_basis,i) 
        Else 
          ProcedureReturn "-1" 
        EndIf 
        i+1
      Next 
    Else
      i = 0
      For *ziffer_p = @Zahl+l-1 To @Zahl Step -1
        If 47 < *ziffer_p\b And *ziffer_p\b < 58 
          dec + (*ziffer_p\b-48) * Pow(in_basis,i) 
        ElseIf 64 < *ziffer_p\b And *ziffer_p\b < 91 
          dec + (*ziffer_p\b-55) * Pow(in_basis,i) 
        Else  
          ProcedureReturn "-1" 
        EndIf 
        i+1
      Next 
    EndIf 
    ;wenn Ausgabebasis 10 ist muss nicht mehr gerechnet werden, denn 
    ;die Zahl wird ja immer zuerst ins Dezimalsystem umgerechnet 
    If out_basis = 10 
      ergebnis = Str(dec) 
    Else ;ansonsten muss die Zahl berechnet werden 
      Repeat 
        rest = dec % out_basis 
        dec / out_basis 
        If rest > 9 
          rest_s = Chr(55 + rest) 
        Else 
          rest_s = Str(rest) 
        EndIf 
        ergebnis + rest_s 
      Until dec = 0 
    EndIf 
    ProcedureReturn ergebnis ;die Zahl wird an das Hauptprogramm zurückgegeben 
  EndIf  
  ProcedureReturn "-1" 
EndProcedure 

Zahl.s = "ff" ;die Zahl muss zur Basis passen sonst gibt die Procedure -1 zurück 
in_basis.l = 16 ;in_basis und out_basis müssen größer als 1 
out_basis.l = 10 ;und kleiner als 37 sein 

Zahl = MultiConvert(Zahl,in_basis,out_basis) 
If Zahl <> "-1" 
  Debug Zahl 
EndIf 
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Kristel
Beiträge: 72
Registriert: 30.08.2004 00:17

Beitrag von Kristel »

Gegenschlag *esnichtlassenkonnt*

Code: Alles auswählen

Procedure.s MultiConvert(Zahl.s,in_basis.l,out_basis.l) ;kovertiert jede Stringzahl in ein anderes Zahlensystem 
  Protected l.l, ziffer.s, i.l, ziffer_l.l, dec.l, ASC_Wert.l, ergebnis.s, rest.l, *ziffer_p.BYTE 
  Zahl = UCase(Trim(Zahl)) 
  l = Len(Zahl) 
  ;Prüfen ob die Zahlensystembereiche eingehalten wurden und ob, ein String übergeben wurde 
  If l > 0 And 1 < in_basis And in_basis < 37 And 1 < out_basis And out_basis < 37 
    ;Prüfung ob die Zeichen in der angegeben Basis erlaubt sind und wenn ja werden sie im 
    ;Dezimalsystem ausgegeben und addiert
    i = 0
    If in_basis < 11 
      For *ziffer_p = @Zahl+l-1 To @Zahl Step -1 
        If 47 < *ziffer_p\b And *ziffer_p\b < 58 
          dec + (*ziffer_p\b-48) * Pow(in_basis,i) 
        Else 
          ProcedureReturn "-1" 
        EndIf 
        i+1 
      Next 
    Else 
      For *ziffer_p = @Zahl+l-1 To @Zahl Step -1 
        If 47 < *ziffer_p\b And *ziffer_p\b < 58 
          dec + (*ziffer_p\b-48) * Pow(in_basis,i) 
        ElseIf 64 < *ziffer_p\b And *ziffer_p\b < 91 
          dec + (*ziffer_p\b-55) * Pow(in_basis,i) 
        Else  
          ProcedureReturn "-1" 
        EndIf 
        i+1 
      Next 
    EndIf 
    ;wenn Ausgabebasis 10 ist muss nicht mehr gerechnet werden, denn 
    ;die Zahl wird ja immer zuerst ins Dezimalsystem umgerechnet 
    If out_basis = 10 
      ergebnis = Str(dec) 
    ElseIf out_basis < 10 ;ansonsten muss die Zahl berechnet werden
      Repeat 
        rest = dec % out_basis 
        dec / out_basis 
        ergebnis + Str(rest) 
      Until dec = 0
    Else  
      Repeat 
        rest = dec % out_basis 
        dec / out_basis 
        If rest > 9 
          ergebnis + Chr(55 + rest) 
        Else 
          ergebnis + Str(rest) 
        EndIf 
      Until dec = 0 
    EndIf 
    ProcedureReturn ergebnis ;die Zahl wird an das Hauptprogramm zurückgegeben 
  EndIf  
  ProcedureReturn "-1" 
EndProcedure 

Zahl.s = "ff" ;die Zahl muss zur Basis passen sonst gibt die Procedure -1 zurück 
in_basis.l = 16 ;in_basis und out_basis müssen größer als 1 
out_basis.l = 10 ;und kleiner als 37 sein 

Zahl = MultiConvert(Zahl,in_basis,out_basis) 
If Zahl <> "-1" 
  Debug Zahl 
EndIf
End
Würdest du jetzt bitte aufhören ? *Unentschiedenanbiet* Will hier keinen inoffiziellen Speedcontest :wink:
Antworten