Convert.ToString() Base Limitations

  • Thread starter Thread starter Jonathan Wood
  • Start date Start date
J

Jonathan Wood

Does anyone know why the toBase argument in Convert.ToString() is limited to
2, 8, 10, or 16? It takes virtually the same code to support all base values
from 2 to 36.

And can anyone tell me if the .NET library provides the means to convert a
number to a string using base-36?

Thanks.
 
Jonathan Wood said:
Does anyone know why the toBase argument in Convert.ToString() is limited to
2, 8, 10, or 16? It takes virtually the same code to support all base values
from 2 to 36.

And can anyone tell me if the .NET library provides the means to convert a
number to a string using base-36?

I haven't seen such a call anywhere in the library, but it wouldn't be
hard to write an arbitrary conversion which either took just a base and
used the alphabet, or took a character array or string where each
character is a "digit" to use in the output, where the base is just the
length of the array/string.

If you want, I could try to put that into my MiscUtil library over the
weekend...
 
Like I indicated before, the same code that generates base-2 or base-10
strings can also generate base-36 so I really don't understand the
limitation. Writing my own simply duplicates that code.

At any rate, I did write my own. I'm a long time programmer but new to C# so
if anyone sees anything I could've done better, I'm open to constructive
criticism.

Thanks.

static string _alphaDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

string UIntToString(UInt32 value, UInt32 toBase)
{
string result = "";

do
{
UInt32 digitValue = (value % toBase);
result += _alphaDigits[(int)digitValue];
value /= toBase;
} while (value != 0);
result = ReverseString(result);
return result;
}

UInt32 StringToUInt(string s, UInt32 toBase)
{
UInt32 result = 0;

for (int i = 0; i < s.Length; i++)
{
result *= toBase;
result += (UInt32)_alphaDigits.IndexOf(s);
}
return result;
}

string ReverseString(string s)
{
string result = "";

for (int i = 0; i < s.Length; i++)
result = s.Substring(i, 1) + result;
return result;
}
 
Jonathan Wood said:
Like I indicated before, the same code that generates base-2 or base-10
strings can also generate base-36 so I really don't understand the
limitation. Writing my own simply duplicates that code.

At any rate, I did write my own. I'm a long time programmer but new to C# so
if anyone sees anything I could've done better, I'm open to constructive
criticism.

Thanks.

static string _alphaDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

Firstly, I'd make that a const string, and give it an appropriate
conventional name:

const sting AlphaDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string UIntToString(UInt32 value, UInt32 toBase)

I'd make that

static string UInt32ToString(uint value, uint toBase)

Making the type name the .NET name makes it easier to understand from
other languages, but using the C# aliases gives colouring in Visual
Studio.
{
string result = "";

do
{
UInt32 digitValue = (value % toBase);
result += _alphaDigits[(int)digitValue];
value /= toBase;
} while (value != 0);
result = ReverseString(result);
return result;
}

This is a bad way of building up a string - use StringBuilder instead.
See http://www.pobox.com/~skeet/csharp/stringbuilder.html
In this particular case you'll never actually have much performance
penalty, but it's a good idea to get into good habits. It also means
you can reverse the contents of the StringBuilder in place.
UInt32 StringToUInt(string s, UInt32 toBase)
{
UInt32 result = 0;

for (int i = 0; i < s.Length; i++)
{
result *= toBase;
result += (UInt32)_alphaDigits.IndexOf(s);
}
return result;
}


Other than the lack of error checking, this seems reasonable. (With the
same suggestions about naming, making it static etc)
string ReverseString(string s)
{
string result = "";

for (int i = 0; i < s.Length; i++)
result = s.Substring(i, 1) + result;
return result;
}

Again, I'd use StringBuilder - but I'd probably write it as:

static string ReverseString (string s)
{
return Reverse(new StringBuilder(s)).ToString();
}

// Note: returns the StringBuilder reference passed in for
// ease of method chaining - the contents are reversed
// in-place.
static StringBuilder Reverse (StringBuilder builder)
{
int lowIndex = 0;
int highIndex = builder.Length-1;

while (lowIndex <= highIndex)
{
char c = builder[lowIndex];
builder[lowIndex] = builder[highIndex];
builder[highIndex] = c;
lowIndex++;
highIndex--;
}
}

All of that is completely untested, by the way...
 
Thanks for the feedback. I've printed your post and will go over it
carefully later.

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com


Jon Skeet said:
Jonathan Wood said:
Like I indicated before, the same code that generates base-2 or base-10
strings can also generate base-36 so I really don't understand the
limitation. Writing my own simply duplicates that code.

At any rate, I did write my own. I'm a long time programmer but new to C#
so
if anyone sees anything I could've done better, I'm open to constructive
criticism.

Thanks.

static string _alphaDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

Firstly, I'd make that a const string, and give it an appropriate
conventional name:

const sting AlphaDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string UIntToString(UInt32 value, UInt32 toBase)

I'd make that

static string UInt32ToString(uint value, uint toBase)

Making the type name the .NET name makes it easier to understand from
other languages, but using the C# aliases gives colouring in Visual
Studio.
{
string result = "";

do
{
UInt32 digitValue = (value % toBase);
result += _alphaDigits[(int)digitValue];
value /= toBase;
} while (value != 0);
result = ReverseString(result);
return result;
}

This is a bad way of building up a string - use StringBuilder instead.
See http://www.pobox.com/~skeet/csharp/stringbuilder.html
In this particular case you'll never actually have much performance
penalty, but it's a good idea to get into good habits. It also means
you can reverse the contents of the StringBuilder in place.
UInt32 StringToUInt(string s, UInt32 toBase)
{
UInt32 result = 0;

for (int i = 0; i < s.Length; i++)
{
result *= toBase;
result += (UInt32)_alphaDigits.IndexOf(s);
}
return result;
}


Other than the lack of error checking, this seems reasonable. (With the
same suggestions about naming, making it static etc)
string ReverseString(string s)
{
string result = "";

for (int i = 0; i < s.Length; i++)
result = s.Substring(i, 1) + result;
return result;
}

Again, I'd use StringBuilder - but I'd probably write it as:

static string ReverseString (string s)
{
return Reverse(new StringBuilder(s)).ToString();
}

// Note: returns the StringBuilder reference passed in for
// ease of method chaining - the contents are reversed
// in-place.
static StringBuilder Reverse (StringBuilder builder)
{
int lowIndex = 0;
int highIndex = builder.Length-1;

while (lowIndex <= highIndex)
{
char c = builder[lowIndex];
builder[lowIndex] = builder[highIndex];
builder[highIndex] = c;
lowIndex++;
highIndex--;
}
}

All of that is completely untested, by the way...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Back
Top