Base 2 through 36 conversion
Monkey Forums/Monkey Code/Base 2 through 36 conversion
| ||
EDIT (Last day of 2013): I updated the code from it's '09 BlitzMax converted version. Important Note: Numbers larger than an integer will not convert correctly. This is because the maximum value possible for it to use while converting is 0xFFFFFFFF EDIT: This is now part of a php based Monkey library at Google Code - http://code.google.com/p/nrgs-monkey-lib/ I've been working on replicating a bunch of php functions into BlitzMax and Monkey. This took me a bit more time than I thought it would, to figure out how to convert between bases. So I'm sharing it here. I figure it has some use, especially for storing or packing large numbers. I think there may be ways to optimize this function, but I'm not familiar enough with Monkey yet to be sure. Function #Rem Summary: Convert a number between arbitrary bases Returns a String containing number represented in base tobase. The base in which number is given is specified in frombase. Both frombase And tobase have To be between 2 And 36, inclusive. Digits in numbers with a base higher than 10 will be represented with the letters a-z, with a meaning 10, b meaning 11 And z meaning 35. #End Function BaseConvert:String( number:String, fromBase:Int, toBase:Int ) If fromBase > 1 And fromBase < 37 And toBase > 1 And toBase < 37 Local charlist := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" Local inputArray:Int[number.Length] Local outputStack := New StringStack() Local givenLength := 0 Local output := "" Local outVal := 0 Local calcVal := 0 Local calcMod := 0 Local baseMul := 1 Local i := 0 number = number.ToUpper() ' So as a quick explanation of what's going on ' Step one, push the individual values in their decimal equivalent form to the top of the stack For i = 0 Until number.Length inputArray[i] = charlist.Find(number[i..i + 1]) Next ' Step two, starting from the rightmost value at 1, start to multiply the value that the ' decimal value is then multiplied by to get the decimal equivalent of whatever base ' the inputted number is. For i = inputArray.Length() - 1 To 0 Step - 1 If i < inputArray.Length() - 1 baseMul *= fromBase End calcVal += inputArray[i] * baseMul Next ' Step three, the math formula that finds the values in decimal form While calcVal <> 0 calcMod = calcVal Mod toBase outputStack.Push(calcMod) calcVal -= calcMod calcVal /= toBase Wend ' Step four, pop the value from the stack to get the slice location in the charlist string givenLength = outputStack.Length() For i = 1 To givenLength outVal = Int(String(outputStack.Pop())) output += charlist[outVal..outVal + 1] Next If output.Length Then Return output Return "0" End Return "" End Usage Function Main:Int() Print BaseConvert("ZZVZZX", 36, 10) Print "2176595709 <-- Expected" Print BaseConvert("FFFFFFFF", 16, 10) Print "4294967295 <-- Expected" Print BaseConvert("1295", 10, 36) Print "ZZ <-- Expected" Print BaseConvert("010", 36, 2) Print "100100 <-- Expected" Print BaseConvert("000JKH0", 28, 7) Print "3453050 <-- Expected" Print BaseConvert("00000", 28, 7) Print "0 <-- Expected" Return 0 End |