This Function is a Base converter that will take in any value from any base for [2,36] (I believe [] means inclusive, if I am mistaken, please correct me.)
The main difference between mine and many other converters of this type is that I use the BigInteger class (so .NET 4.0 is required), this makes it able to work with VERY large numbers, I think the only limit on it is at one part of my code I need to pass into a .substring an integer, so this limits the amount of digits of your number to about 2.4 billion (it is commented in my code where that is)
To use it, copy it into your code (ok.. hopefully that part was obvious):
Fully improved code on next post: (went from a 220 line function to a 72 or so line class) huge difference when switching from a select....case to having what i needed inside of a list and using .indexof and .item
Last edited by patplays852; Jul 20th, 2010 at 07:02 PM.
Reason: update
Public Function IsValidNumBase(ByVal str1 As String, ByVal base As Byte) As Boolean
For x As Integer = 0 To str1.Length - 1
If Not (numLetter.Contains(str1.Substring(x, 1).ToUpper)) Or ((base - 1) < numLetter.IndexOf(str1.Substring(x, 1).ToUpper)) Then
Return False
End If
Next
Return True
End Function
Function Convert(ByVal base As Byte, ByVal convert_to As Byte, ByVal inputnumber As String) As String
'if the base or convert_to base are less than 2 or greater than 36, return:
If (base < 2 Or base > 36) Or (convert_to < 2 Or convert_to > 36) Then
Return "Invalid base"
End If
'If the value is non alphanumeric or is incorrect for its base (ex "FF" for base 15 and under) then we'll return this error:
If Not (IsValidNumBase(inputnumber, base)) Then
Return "Invalid Input"
End If
'if the current base and the base to convert into are the same, return numtoconvert
If base = convert_to Then
Return inputnumber
End If
Dim decvaltoconvert As BigInteger = 0
'convert into a decimal value before working w/ it
If (base = 10) Then
decvaltoconvert = CType(inputnumber, BigInteger)
Else
Dim place As Integer = 0
For x As Integer = inputnumber.Length - 1 To 0 Step -1
'only using integer because .substring will not accept a biginteger value, besides, if its over 2.4billion digits long, u don't want to use this program anyway.
I appreciate any comments you may have, and ideas on how to improve the code!
This is v2 of the code (before i was using select....case instead of the list... trimmed off nearly 180 lines of code when i switched to lists =)
for general purpose, the code runs near instantly (runs at 0ms) using stopwatch timer in system.diagnostics. Once you reach about 20,000 digits it starts to slow down quite a bit.
Test Results: (conversion from a string of x "z" into binary (so from max num base 36 to base 2)
At the times of these tests I did have firefox open, with 1 tab (on the page to type this up lol), vs2010 of course (im running in debug mode btw, not sure if release mode runs faster because of less overhead), alsong music player, trillian chat, notepad++ (for the string of "z", has a nice character count in it.
Running windows 7 ultimate 32bit, 3 GB RAM, 2.4GHz single core CPU.
Test : 500 "z"'s took 32ms
Test : 1000 "z"'s took 125ms
Test : 5000 "z"'s took 5038ms
Test : 10000 "z"'s took 29059ms
Test : 15000 "z"'s took 86625ms
Test : 20000 "z"'s took 203303ms
Now, to put that all into perspective, the first test: 500 "z"'s in base 10 is:
1416610262383486172379625252491522441664047183091019132232354743214061894759648643634766 1333869287260068907949302029484915942402681211620694598046617844295512220793103312980549 5915371609590530279406241175980034175030157226974281761556003622631285675902995117766865 9286207437632823299032510124868012377691457648281509578456812298622189041183773757009886 4613342090972756469661488216176894465388028416768338495326989675118087222767384596111351 3049578690252738029782817837319299664682105792298300695566989289373425089883407923357377 4471937659850690897713529198311772264826917794715465769751707499344151552683988707340019 1797445153760221695723268255006134044062503100710134200414607696976757837002911389023284 338696251543694980946202137938610119300450795091488653253649628649410789375
^ 779 digit long number *wish I could see some of your jaws drop at that like mine did...
inserted some new lines so it didn't screw up the page.
Last edited by patplays852; Jul 20th, 2010 at 08:23 PM.
Imports System.Numerics
Public Class BaseConverter
Dim numLetter As List(Of String) = New List(Of String) _
(New String() {"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"})
Public Function IsValidNumBase(ByVal str1 As String, ByVal base As Byte) As Boolean
For x As Integer = 0 To str1.Length - 1
If Not (numLetter.Contains(str1.Substring(x, 1).ToUpper)) Or ((base - 1) < numLetter.IndexOf(str1.Substring(x, 1).ToUpper)) Then
Return False
End If
Next
Return True
End Function
Function Convert(ByVal base As Byte, ByVal convert_to As Byte, ByVal inputnumber As String) As String
'if the base or convert_to base are less than 2 or greater than 36, return:
If (base < 2 Or base > 36) Or (convert_to < 2 Or convert_to > 36) Then
Return "Invalid base"
End If
'If the value is non alphanumeric or is incorrect for its base (ex "FF" for base 15 and under) then we'll return this error:
If Not (IsValidNumBase(inputnumber, base)) Then
Return "Invalid Input"
End If
'if the current base and the base to convert into are the same, return numtoconvert
If base = convert_to Then
Return inputnumber
End If
Dim decvaltoconvert As BigInteger = 0
'convert into a decimal value before working w/ it
If (base = 10) Then
decvaltoconvert = CType(inputnumber, BigInteger)
Else
Dim place As Integer = 0
For x As Integer = inputnumber.Length - 1 To 0 Step -1
'only using integer because .substring will not accept a biginteger value, besides, if its over 2.4billion digits long, u don't want to use this program anyway.
decvaltoconvert += CType((numLetter.IndexOf(inputnumber.Substring(x, 1).ToUpper) * (BigInteger.Pow(base, CInt(place)))), BigInteger)
place += 1
Next
End If
'if the output base is base 10, no need to work with it further
If convert_to = 10 Then
Return decvaltoconvert.ToString
End If
'convert into the desired base
Dim returnstr As String = ""
While decvaltoconvert > 0
Dim tempval As BigInteger = 0
BigInteger.DivRem(decvaltoconvert, CType(convert_to, BigInteger), tempval) 'modulus division with the Biginteger class, sets tempval to the remainder
'Note that if u put tempval = .Divrem(....) then it sets tempval equal to decvaltoconvert / convert base, which is useless for what we need.
returnstr = String.Concat(returnstr, numLetter.Item(CType(tempval, Integer)))
decvaltoconvert = CType(BigInteger.Divide(decvaltoconvert, convert_to), BigInteger)
End While
returnstr = StrReverse(returnstr)
Return returnstr
End Function
End Class