Patplays852 0 Newbie Poster

Below is a Base Conversion Class that will take in any number (up to around 2.4 billion digits (limited by string.substring's integer property)), It will convert from any base to any base (from 2-36 inclusive)

It does have some simple error handling such as if you enter a number that is incorrect for its base (ex: FF in base 15 and under), it will also throw an error if you enter a base lower than 2 or higher than 36.

This code does use the BigInteger class so .NET 4.0 is a requirement, you must also add a reference (as well as an import) to System.Numerics

Here are is an example of how to use this class:

Dim converter as New BaseConverter
Dim Number1Toconvert as Integer = 255
Dim currentBase as Byte = 10
Dim targetBase as Byte = 16

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"})

'returns if the number is valid for the selected base (see above example) *outside of code*
     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
          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)
               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
          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

Comments are welcome (and expected), I'd love to know how to improve the code! This is v2 of the code (before i was using 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:


^ 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.

When I made this I was in the code snippets forum, so I thought it would have been a submission there automatically...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.18 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.