james3mg Posted September 23, 2008 Share Posted September 23, 2008 (edited) Here is the culmination of a UDF script I've been thinking about for some time...it allows you to convert a number into another base. The output is a string, so it's ready for DISPLAY in your scripts, but also since it's a string, you can't expect AutoIt to know how to perform mathematical operations in the string's base.There are three functions in the script (and no #includes), so it's nice and lightweight. _ToDec() allows you to convert a number in a supported base into a decimal number, _ToBase() allows you to convert a decimal number into a supported base, and _BaseToBase() uses both of the above to convert one supported base to another in one operation.Supported bases are: all bases between 2 and 62 (inclusive). Decimal bases are supported and correctly rendered, though I've yet to hear of a useful application for them. Negative bases ARE NOT SUPPORTED. I love the theory behind them, but when I go to apply them, they confuse me quickly. Digits representing numbers greater than 9 are represented by case-sensitive english letters, capitals first.The numbers being converted do not have to be integers, though numbers generated by decimal conversions may surprise you (or they may not, of course). For instance. 1 in binary is 1 in decimal. But 1.1 in binary is 1.5 in decimal, since .1 in binary is HALF of 1. Likewise, 1.1 in decimal is 1.0625 in hex (base 16), since .1 represents 1/16th of 1.I hope you find this useful- the defaults I've selfishly set up for my most common tasks- I wrote this so I could have an easy way of actually viewing a real binary string (only 1s and 0s) rather than its hex representation. Hopefully I didn't miss any other, more obvious, application with better defaults Let me know what you think! >_<Edit: updated on 9/24/2008, due to an unintentional previous lack of support for converting negative numbers. Negative bases are still not supported.You can use the below code to test the include file, but note the ConsoleWrite tends to truncate number strings:$DecNum=_ToDec(11001.1,2) If NOT @error Then ConsoleWrite($DecNum&@CRLF) Else ConsoleWrite("Error: "&@error&@CRLF) EndIf $HexNum=_ToBase(25.5,2) If NOT @error Then ConsoleWrite($HexNum&@CRLF) Else ConsoleWrite("Error: "&@error&@CRLF) EndIf $ConvNum=_BasetoBase("F") If NOT @error Then ConsoleWrite($ConvNum&@CRLF) Else ConsoleWrite("Error: "&@error&@CRLF) EndIfBaseConv.au3 include file:expandcollapse popup#include-once Global $_BCaddlNums[63]=[0,1,2,3,4,5,6,7,8,9,"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"] ; Function: _ToDec() ; Author: james3mg ; Summary: Converts a number represented in a string from any positive base less than base 63 into decimal (base 10) ; Numbers greater than 9 should be represented by English letters in ascending alphabetical order; capitols first. CASE SENSITIVE! ; See the $_BCaddlNums array at the top of this file for an ordered ranking of digits. ; Negative bases are not supported; they confuse me too much in practice, though the theory is elegant. ; Fractional bases (i.e. base 10.25) are correctly supported, but I can't imagine a useful application of them. ; Arguments: ; $_BCnum The string to convert to decimal (base 10) (required) ; $_BCbase The base to convert $_BCnum from (optional: default is 16) ; Return value: ; Success: A string representing the number expressed in the base requested ; Failure: Returns a blank string ("") and sets @error as following: ; @error=1 number string contains non-alphanumeric digits ; @error=2 invalid base number provided ; @error=3 a digit provided was not in the base provided (for instance a 2 occured in an allegedly binary string) Func _ToDec($_BCnum,$_BCbase=16);converts the string from any positive base less than 63 into decimal (base 10) If $_BCbase=-1 Or $_BCbase=Default Then $_BCbase=16 If NOT IsNumber($_BCbase) OR $_BCbase > 62 OR $_BCbase < 1 Then Return SetError(2) Local $_BCsign="" If StringLeft($_BCnum,1)="-" Then $_BCsign="-" $_BCnum=StringTrimLeft($_BCnum,1) EndIf Local $_SplitNum=StringSplit(String($_BCnum),"."),$_SplitNumInt=StringSplit($_SplitNum[1],""),$_i,$_n,$_BCreturnVal="" If NOT StringIsAlNum($_SplitNum[1]) Then Return SetError(1);number contains non-alphanumeric digits (to the left of the decimal) If $_SplitNum[0] <> 1 Then If $_SplitNum[0] <> 2 Then Return SetError(1);number contains non-alphanumeric digits (in this particular case, too many decimal points) If NOT StringIsAlNum($_SplitNum[2]) Then Return SetError(1);number contains non-alphanumeric digits (to the right of the decimal) Local $_SplitNumDec=StringSplit($_SplitNum[2],"") EndIf ;from here, we can guarentee the number passed the function could be a number in some base For $_i=1 To $_SplitNumInt[0] For $_n=10 To $_BCbase-1 If $_SplitNumInt[$_i]==$_BCaddlNums[$_n] Then $_SplitNumInt[$_i]=$_n ExitLoop EndIf Next If NOT StringIsInt($_SplitNumInt[$_i]) OR $_SplitNumInt[$_i] > $_BCbase Then Return SetError(3);digit out of base range (for instance, 3 included in string given as binary) Next If $_SplitNum[0]=2 Then;if there was a decimal point For $_i=1 To $_SplitNumDec[0] For $_n=10 To $_BCbase-1 If $_SplitNumDec[$_i]==$_BCaddlNums[$_n] Then $_SplitNumDec[$_i]=$_n ExitLoop EndIf Next If NOT StringIsInt($_SplitNumDec[$_i]) OR $_SplitNumDec[$_i] > $_BCbase Then Return SetError(3);digit out of base range Next EndIf For $_i=1 To $_SplitNumInt[0] $_BCreturnVal+=$_BCbase^($_i-1)*$_SplitNumInt[$_SplitNumInt[0]-($_i-1)] Next If $_SplitNum[0]=2 Then;if there was a decimal point For $_i=1 To $_SplitNumDec[0] $_BCreturnVal+=$_BCbase^(0-$_i)*$_SplitNumDec[$_i] Next EndIf Return SetError(0,0,$_BCsign&$_BCreturnVal) EndFunc ; Function: _ToBase() ; Author: james3mg ; Summary: Converts a number represented in a string from any positive base less than base 63 into decimal (base 10) ; Numbers greater than 9 are represented by English letters in ascending alphabetical order; capitols first. CASE SENSITIVE! ; See the $_BCaddlNums array at the top of this file for an ordered ranking of digits. ; Decimals are supported, but remember that 1.1 in binary is represented by 1.5 in decimal, since .1 is HALF of a whole number in binary! (Doubling .1 in binary will give you 1.0) ; !!! NOTE: the output of this function is a STRING! Do not expect AutoIt to know how to perform mathematical operations on the result in the correct base! ; If you want to perform such operations, convert into decimal, run the operation, and convert back. ; Negative bases are not supported; they confuse me too much in practice, though the theory is elegant. ; Fractional bases (i.e. base 10.25) are correctly supported, but I can't imagine a useful application of them. ; Arguments: ; $_BCnum The string to convert to the specified base (required) ; $_BCbase The base to convert $_BCnum into (optional: default is 16) ; $_BClimit The maximum number of decimal points returned (numbers to the RIGHT of the decimal point). (optional: default is 12) Note this has no effect on the number of digits to the left of the point (or if there is no point). ; Return value: ; Success: A string representing the number expressed in the base requested ; Failure: Returns a blank string ("") and sets @error as following: ; @error=1 string is not a decimal (base 10) number ; @error=2 invalid base number provided Func _ToBase($_BCnum,$_BCbase=16,$_BClimit=12);converts the decimal (base 10) string into any positive base less than 63 If $_BCbase=-1 OR $_BCbase=default Then $_BCbase=16 If $_BClimit=-1 OR $_BClimit=default Then $_BCbase=12 If NOT IsNumber($_BCbase) OR $_BCbase > 62 OR $_BCbase < 1 Then Return SetError(2) Local $_BCsign="" If StringLeft($_BCnum,1)="-" Then $_BCsign="-" $_BCnum=StringTrimLeft($_BCnum,1) EndIf Local $_SplitNum=StringSplit(String($_BCnum),"."),$_i,$_BCreturnVal="" If Not StringIsDigit($_SplitNum[1]) Then Return SetError(1);not a decimal number If $_SplitNum[0] <> 1 Then If $_SplitNum[0] <> 2 Then Return SetError(1);not a decimal number (too many decimal points) If Not StringIsDigit($_SplitNum[2]) Then Return SetError(1);not a decimal number right of the decimal point EndIf ;now we can assume the number is valid Local $_MaxExp=Floor(Log($_BCnum)/Log($_BCbase));find out the digit length in destination base (actual digit length is 1 greater than this number, since 1 has a length of 1 and is 10^0) For $_i=$_MaxExp To 0 Step -1;loop through each digit to find the highest multiplier without going over $_BCreturnVal&=$_BCaddlNums[Floor($_BCnum/($_BCbase^$_i))] $_BCnum-=Floor($_BCnum/($_BCbase^$_i))*$_BCbase^$_i Next If $_SplitNum[0]=1 Then Return SetError(0,0,$_BCsign&$_BCreturnVal) ;if you get here, there's still decimal points to tally $_BCreturnVal&="." For $_i=-1 To $_BClimit*-1 Step -1 $_BCreturnVal&=$_BCaddlNums[Floor($_BCnum/($_BCbase^$_i))] $_BCnum-=Floor($_BCnum/($_BCbase^$_i))*$_BCbase^$_i If $_BCnum=0 Then ExitLoop;don't add trailing zeros if an exact conversion is found Next Return SetError(0,0,$_BCsign&$_BCreturnVal) EndFunc ; Function: _BaseToBase() ; Author: james3mg ; Summary: Converts a number represented in a string from any positive base less than base 63 into decimal (base 10) ; Numbers greater than 9 are represented by English letters in ascending alphabetical order; capitols first. CASE SENSITIVE! ; See the $_BCaddlNums array at the top of this file for an ordered ranking of digits. ; Decimals are supported, but remember that 1.1 in binary is represented by 1.5 in decimal, since .1 is HALF of a whole number in binary! ; !!! NOTE: the output of this function is a STRING! Do not expect AutoIt to know how to perform mathematical operations on the result in the correct base! ; If you want to perform such operations, convert into decimal, run the operation, and convert back. ; Negative bases are not supported; they confuse me too much in practice, though the theory is elegant. ; Fractional bases (i.e. base 10.25) are correctly supported, but I can't imagine a useful application of them. ; Arguments: ; $_BCnum The string to convert to the specified base (required) ; $_BCbaseOrig The base to convert $_BCnum from (optional: default is 16) ; $_BCbaseFinal The base to convert $_BCnum into (optional: default is 2) ; $_BClimit The maximum number of decimal points returned (numbers to the RIGHT of the decimal point). (optional: default is 12) Note this has no effect on the number of digits to the left of the point (or if there is no point). ; Return value: ; Success: A string representing the number expressed in the base requested ; Failure: Returns a blank string ("") and sets @error as following: ; @error=1 number string contains non-alphanumeric digits ; @error=2 invalid input base number provided ; @error=3 a digit provided was not in the base provided (for instance a 2 occured in an allegedly binary string) ; @error=4 unknown error (this should never happen- it means that _ToDec misfired somehow ; @error=5 invalid output base number provided Func _BaseToBase($_BCnum,$_BCbaseOrig=16,$_BCbaseFinal=2,$_BClimit=12);errors 1-3 match errors 1-3 in _ToDec(); errors 4-5 match errors 1-2 in _ToBase() Local $_BCconv=_ToDec($_BCnum,$_BCbaseOrig) If @error Then Return SetError(@error) $_BCconv=_ToBase($_BCconv,$_BCbaseFinal,$_BClimit) If @error Then Return SetError(@error+3) Return SetError(0,0,$_BCconv) EndFunc Edited September 24, 2008 by james3mg "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
BillLuvsU Posted September 24, 2008 Share Posted September 24, 2008 This is very good. Good job. [center][/center]Working on the next big thing.Currently Playing: Halo 4, League of LegendsXBL GT: iRememberYhslaw Link to comment Share on other sites More sharing options...
james3mg Posted September 24, 2008 Author Share Posted September 24, 2008 Thanks! >_< See the first post for an updated version; previously I'd forgotten to include support for converting negative numbers! "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now