ScriptLogic.com: Windows Management…Point, Click, Done

Home » KiXtart Resource Center » Function Library » CnvtBase( )


 Author: W.M. Hinsch (New Mexico Mark)
 Published: 2002-Feb-05
 Last revised:  2002-Feb-05

Function:
CnvtBase

 
Category: Math
 
Action:
Converts numbers from any base (2-36) to any base (2-36). i.e. base 2=binary, 8=octal, 10=decimal, 16=hex, etc.

 
Syntax
CNVTBASE ( number, [oldbase], [newbase] ) 

 
Parameters:
Name Type Optional Description
number String Required The number (passed as a string) to convert from.

oldbase String Required The base that number is in. (If not supplied or out of range, cnvtbase will try to "guess" whether it is binary, octal, decimal, hexadecimal, or some base between 17 and 36).

newbase String Required The base to which the number will be converted. If not supplied or out of range, decimal (base 10) will be used.


 
Remarks:
Use this function to convert among several bases. I.e. when a number must be represented in decimal, hex, and binary formats. I originally wrote this as a training exercise when learning a different programming language, but it has proven helpful in many cases, so I've converted the logic to KiXtart. The key information contained is the generalized algorithm for converting to base 10 and to other bases containing alpha characters. It also demonstrates the need for knowing which data type you are working with at any given time! KiXtart is pretty flexible, but it can't read minds.

"Number" is a string representing a number, base 2 - 36. Oldbase and newbase may be any number 2 - 36. If oldbase is not supplied, the function will "guess" the old base as base 2, 8, 10, 16, or 17-36 depending on the highest value "digit" contained in the string. If the string is prepended with a hyphen "-" (i.e. negative number), the hyphen will be preserved in the return string.

IMPORTANT: The function returns the converted number as a STRING in order to correctly handle bases greater than 10.

One final note: The function will return a "0" if the supplied number string contains any non-alphanumeric characters besides a leading hyphen (-). This means the function could even be used to test whether a string is alphanumeric.

Unusual behaviors: This function will produce unreliable results for numbers that evaluate to a base 10 number outside the range of -2,147,483,647 to 2,147,483,647. Also: If newbase is not supplied or is out of range (< 2 or > 36), the function will convert to decimal (base 10).

 
Returns:
The function returns a string representing the number in the new base specified (or base 10 if none specified).

 
Dependencies:
None.

 
Examples:
CnvtBase("5A23") ; Returns "23075" (base 16 to base 10)
CnvtBase("1010") ; Returns "10" (base 2 to base 10)
CnvtBase("1010",10,2) ; Returns "1111110010" (base 10 to base 2)
CnvtBase("54321",10,16) ; Returns "D431" (base 10 to base 16)
CnvtBase("T#NST##FL") ; Returns "0" (The supplied string is not alphanumeric) 
$strTest = CnvtBase("54321") ; $strTest will contain "22737" (converted octal to decimal.)

; -- Code Example: --
? "Please supply an integer to convert to Hex, Octal, and Binary: "
gets $TempStr
?
"Hex value: " + CnvtBase($TempStr,10,16) ?
"Octal value: " + CnvtBase($TempStr,10,8) ?
"Binary value: " + CnvtBase($TempStr,10,2) ?
"And just for fun... trinary value: " + CnvtBase($TempStr,10,3) ?
sleep 5

-- Return screen from above Code Example when 1024 is entered: --

Please supply an integer to convert to Hex, Octal, and Binary: 1024
Hex value: 400
Octal value: 2000
Binary value: 10000000000
And just for fun... trinary value: 1101221

Source:
function CnvtBase($strNum,optional $intOB,optional $intNB)
    ;*********************************************************
    ;* Function name..: CnvtBase( )
    ;* Author.........: W.M. Hinsch (wmarkh@aol.com)
    ;* Created........: 2001/03/19
    ;* Modified.......: 2001/04/27
    ;* Called by......: None
    ;* Calls..........: None
    ;* Comment........: Converts any base (2-36)
    ;                   into any other base (2-36)
    ;********************************************************* 
    ; Limit the scope of variables to this function...
    ; these should probably be retained even if the code is trimmed.
    dim $strAlpha,$strNew,$strDigit,$strOldNum,$strSign
    dim $intPos,$intDigVal,$intB10,$intPlcNum,$intCtr
    dim $intOldBase,$intNewBase,$varRemain
    
    ; Assign parameters to local variables. This does some basic error-
    ; prevention by forcing the variables to the correct data type.
    $strOldNum = "" + $strNum ; cast to string
    $intOldBase = 0 + $intOB ; cast to number
    $intNewBase = 0 + $intNB ; cast to number
    
    ; Initialize variables. The only variables which really need to be
    ; initialized are $strAlpha and $intPlcNum. The rest are for clarity
    ; and to make converting to other languages easier.
    $intPos = 0 ; Position starting at LSD to MSD
    $intDigVal = 0 ; Base 10 Value of digit
    $intB10 = 0 ; Base 10 Number
    $intPlcNum = 1 ; Value of oldbase raised to intPos power
    $strAlpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    $strNew = "" ; "Number" in new base
    $strSign = "" ; Holds the leading hyphen (-) from strOldNum
    $strDigit = "" ; "Digit" at intPos, including Alpha characters
    
    ; If negative numbers will not be used, this may be eliminated.
    if substr($strOldNum,1,1) = "-"
        $strSign = substr($strOldNum,1,1)
        $strOldNum = substr($strOldNum,2,len($strOldNum) - 1)
    else
        $strSign = ""
    endif
    
    ; This loop checks to make sure all the characters in the supplied
    ; number are alphanumeric. If not, the function exits with a 0 return.
    for $intCtr = 1 to len($strOldNum)
        $strDigit = substr($strOldNum,$intCtr,1)
        if instr($strAlpha,$strDigit) = 0
            $strNew = 0
            goto FUNC_END
        endif
    next
    
    ; This portion attempts to "guess" the base of the number supplied.
    ; It also handles a bad range supplied for the new base.
    ; If this will be explicitly given at all times, this portion may
    ; be eliminated.
    for $intCtr = 1 to 36
        $strDigit = substr($strAlpha,$intCtr,1)
        if instr($strOldNum,$strDigit)
            $intOB = $intCtr ; set to the highest digit found so far
        endif
    next
    
    if $intOldBase < 2 OR $intOldBase > 36
        select
        case $intOB <= 2
            $intOldBase = 2
        case $intOB <= 8
            $intOldBase = 8
        case $intOB <= 10
            $intOldBase = 10
        case $intOB <= 16
            $intOldBase = 16
        case 1
            $intOldBase = $intOB
        endselect
    endif
    
    ; If the user does not specify a new base, or if the new base is
    ; out of range, base 10 will be used as the default.
    if $intNewBase < 2 or $intNewBase > 36
        $intNewBase = 10
    endif
    
    :TO_BASE_10
    $strDigit = substr("$strOldNum",len("$strOldNum") - $intPos,1)
    while "$strDigit" <> ""
        $intDigVal = instr($strAlpha,"$strDigit") - 1
        $intB10 = $intB10 + ($intDigVal * $intPlcNum)
        $intPlcNum = $intPlcNum * $intOldBase
        $intPos = $intPos + 1
        $strDigit = substr("$strOldNum",len("$strOldNum") - $intPos,1)
    loop
    
    :TO_NEW_BASE
    while $intB10 > 0
        ; The following line emulates a "$intB10 mod intNewBase" expression
        $varRemain = $intB10 - (($intB10 / $intNewBase) * $intNewBase)
        ; This puts the remainder digit in the correct format for bases > 10
        $varRemain = substr($strAlpha,$varRemain + 1,1)
        $intB10 = $intB10 / $intNewBase
        $strNew = "$varRemain" + "$strNew"
    loop
    
    :FUNC_END
    $CnvtBase = $strSign + $strNew
endfunction


Created By:
W.M. Hinsch (New Mexico Mark)
False

 

   

 Author: W.M. Hinsch (New Mexico Mark)
 Published: 2002-Feb-05
 Last revised:  2002-Feb-05