Zahlensysteme (2 bis 36) Convert UDF

  • Hi zusammen,


    Ich habe mal ein Skript geschrieben, mit welchem man von jedem beliebigen Zahlensystem zwischen einschließlich 2 und 36 hin- und zurückkonvertieren kann, einschließlich Nachkommastellen.
    Die Funktion:

    ConvertAnySystemToOtherSystem( $numberToConvert , $systemToConvertFrom , $systemToConvertTo )

    übernimmt dabei sämmtliche Konvertierungen.

    Parametrierung:
    Der Parameter $numberToConvert, deklariert die Zahl, welche konvertiert werden soll als String (Erlaubte Zeichen: .,0-9a-zA-Z)
    Der Parameter $systemToConvertFrom, gibt an in welchem Zahlensystem sich $numberToConvert befindet. Der letzte Parameter $systemToConvertTo, gibt das Zahlensystem an, in welches konvertiert werden soll.


    Und hier die Funktionssource's:

    Spoiler anzeigen
    [autoit]

    #include-once

    [/autoit] [autoit][/autoit] [autoit]

    Func ConvertAnySystemToOtherSystem($numberToConvert, $systemToConvertFrom, $systemToConvertTo)
    Local $convertedNumber = 0

    [/autoit] [autoit][/autoit] [autoit]

    ; Use the decimal converters for other conversions
    $convertedNumber = ConvertDecimalToOtherSystem(ConvertAnySystemToDecimal($numberToConvert, $systemToConvertFrom), $systemToConvertTo)

    [/autoit] [autoit][/autoit] [autoit]

    Return $convertedNumber
    EndFunc ;==>ConvertAnySystemToOtherSystem

    [/autoit] [autoit][/autoit] [autoit]

    Func ConvertDecimalToOtherSystem($numberToConvert, $systemToConvertTo)
    If $systemToConvertTo = 10 Then
    Return $numberToConvert
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $systemToConvertTo < 2 Or $systemToConvertTo > 36 Then
    Return SetError(1, 0, "Only number systems between 2 and 36 are allowed")
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Local $convertedNumber = ""

    [/autoit] [autoit][/autoit] [autoit]

    ; Check input for illegal characters and phrases
    If StringInStr($numberToConvert, Chr(95)) Or Not StringRegExp($numberToConvert, "[\d\.\,]{" & StringLen($numberToConvert) & "}") Then
    Return SetError(1, 0, "Character set is invalid")
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Convert the string to lower, to work case insensitive with letters
    ; convert , to .
    $numberToConvert = StringReplace(StringLower($numberToConvert), Chr(44), Chr(46))

    [/autoit] [autoit][/autoit] [autoit]

    ; Declare some later used variables here
    Local $currentPart = 0, $currentNumber = "", $floatCounter, $numberSpace
    Local $temp = "", $remainder = 0, $float

    [/autoit] [autoit][/autoit] [autoit]

    ; Check for float, and declare variables for float conversion
    If StringInStr($numberToConvert, Chr(46)) Then
    $float = StringSplit($numberToConvert, Chr(46), 1)
    If $float[0] <> 2 Then
    Return SetError(1, 0, "Badly formatted float value")
    EndIf
    Else
    $currentNumber = $numberToConvert
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    For $currentPart = 1 To 2
    ; Check, if the input was a float and if we can probably exit here
    If Not StringInStr($numberToConvert, Chr(46)) And $currentPart = 2 Then
    ExitLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Check for float, declare current used data
    If StringInStr($numberToConvert, Chr(46)) Then
    $currentNumber = $float[$currentPart]
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $currentPart = 1 Then
    While $currentNumber > 1
    $remainder = Mod($currentNumber, $systemToConvertTo)
    $currentNumber /= $systemToConvertTo

    [/autoit] [autoit][/autoit] [autoit]

    ; Get replacers for numbers greater than 10, maximum of replacers is 36 (alphanumeric)
    If $remainder >= 0 And $remainder <= 9 Then
    $remainder = Chr($remainder + 48)
    ElseIf $remainder >= 0 And $remainder <= 26 Then
    $remainder = Chr($remainder + 87)
    Else
    Return SetError(1, 0, "Any character does not exist")
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $temp &= $remainder
    WEnd
    $convertedNumber = $temp
    Else
    ; Check for float number
    If $float[$currentPart] <> "" Then
    $float[$currentPart] = Chr(48) & Chr(46) & $float[$currentPart]
    $convertedNumber &= Chr(46)

    [/autoit] [autoit][/autoit] [autoit]

    For $floatCounter = 0 To 7
    $float[$currentPart] = $float[$currentPart] * $systemToConvertTo

    [/autoit] [autoit][/autoit] [autoit]

    ; Multiple check the float number
    If StringInStr($float[$currentPart], Chr(46)) Then
    $temp = StringSplit($float[$currentPart], Chr(46))

    [/autoit] [autoit][/autoit] [autoit]

    If $temp[1] <> "" Then
    $numberSpace &= $temp[1]
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Get the value here
    $float[$currentPart] = Chr(48) & Chr(46) & StringLeft($temp[2], 1)
    Else
    $numberSpace &= $float[$currentPart]
    ExitLoop
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    $convertedNumber &= $numberSpace
    EndIf
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; Add a zero to front, if missed
    If StringLeft($convertedNumber, 1) = Chr(46) Then
    $convertedNumber = Chr(48) & $convertedNumber
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return $convertedNumber
    EndFunc ;==>ConvertDecimalToOtherSystem

    [/autoit] [autoit][/autoit] [autoit]

    Func ConvertAnySystemToDecimal($numberToConvert, $systemToConvertFrom)
    If $systemToConvertFrom = 10 Then
    Return $numberToConvert
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $systemToConvertFrom < 2 Or $systemToConvertFrom > 36 Then
    Return SetError(1, 0, "Only number systems between 2 and 36 are allowed")
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Local $convertedNumber = 0

    [/autoit] [autoit][/autoit] [autoit]

    ; Check input for illegal characters and phrases
    If StringInStr($numberToConvert, Chr(95)) Or Not StringRegExp($numberToConvert, "[\w\.\,]{" & StringLen($numberToConvert) & "}") Then
    Return SetError(1, 0, "Character set is invalid")
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Convert the string to lower, to work case insensitive with letters
    ; convert , to .
    $numberToConvert = StringReplace(StringLower($numberToConvert), Chr(44), Chr(46))

    [/autoit] [autoit][/autoit] [autoit]

    ; Declare some later used variables here
    Local $currentPart = 0, $numberPosition = 0, $currentNumber = ""
    Local $temp = 0, $exponent = 0, $float

    [/autoit] [autoit][/autoit] [autoit]

    ; Check for float, and declare variables for float conversion
    If StringInStr($numberToConvert, Chr(46)) Then
    $float = StringSplit($numberToConvert, Chr(46), 1)
    If $float[0] <> 2 Then
    Return SetError(1, 0, "Badly formatted float value")
    EndIf
    Else
    $currentNumber = $numberToConvert
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    For $currentPart = 1 To 2
    ; Check, if the input was a float and if we can probably exit here
    If Not StringInStr($numberToConvert, Chr(46)) And $currentPart = 2 Then
    ExitLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Check for float, declare current used data
    If StringInStr($numberToConvert, Chr(46)) Then
    $currentNumber = $float[$currentPart]
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Start the main converting process in the following for-loop
    For $numberPosition = StringLen($currentNumber) To 1 Step -1
    $temp = Asc(StringMid($currentNumber, $numberPosition, 1))

    [/autoit] [autoit][/autoit] [autoit]

    ; Get replacers for numbers greater than 10, maximum of replacers is 36 (alphanumeric)
    If $temp >= 48 And $temp <= 57 Then
    $temp -= 48
    ElseIf $temp >= 97 And $temp <= 122 Then
    $temp -= 87
    Else
    Return SetError(1, 0, "Any character does not exist")
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Check for float, and then set exponent, negative one for floating numbers
    If $currentPart = 2 Then
    $exponent = -1 * $numberPosition
    Else
    $exponent = $numberPosition - 1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $convertedNumber += $temp * ($systemToConvertFrom ^ $exponent)
    Next
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $convertedNumber
    EndFunc ;==>ConvertAnySystemToDecimal

    [/autoit]


    Mit freundlichen Grüßen und viel Spaß damit,

    Darknoop

  • Vom 10er System (Dez) zum 16er System (Hex) funktioniert das ganze aucht nicht einwandfrei: (Verkehrter Rückgabewert ausgenommen)

    Dez: 76561198720815197
    Hex Soll: 11000012D55105D
    Hex Ist: 060155d21000011

    Lg, Fabian