# Quickest way to convert a base 10 number to any base in .NET?

I have and old(ish) C# method I wrote that takes a number and converts it to any base:

``````string ConvertToBase(int number, char[] baseChars);
``````

It's not all that super speedy and neat. Is there a good, known way of achieving this in .NET?

I'm looking for something that allows me to use any base with an arbitrary string of characters to use.

This only allows bases 16, 10, 8 and 2:

``````Convert.ToString(1, x);
``````

I want to use this to achieve a massively high base taking advantage of numbers, all lower case and all upper case letters. Like in this thread, but for C# not JavaScript.

Does anyone know of a good and efficient way of doing this in C#?

15

`Convert.ToString` can be used to convert a number to its equivalent string representation in a specified base.

Example:

``````string binary = Convert.ToString(5, 2); // convert 5 to its binary representation
Console.WriteLine(binary);              // prints 101
``````

However, as pointed out by the comments, `Convert.ToString` only supports the following limited - but typically sufficient - set of bases: 2, 8, 10, or 16.

### Update (to meet the requirement to convert to any base):

I'm not aware of any method in the BCL which is capable to convert numbers to any base so you would have to write your own small utility function. A simple sample would look like that (note that this surely can be made faster by replacing the string concatenation):

``````class Program
{
static void Main(string[] args)
{
// convert to binary
string binary = IntToString(42, new char[] { '0', '1' });

string hex = IntToString(42,
new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'});

// convert to hexavigesimal (base 26, A-Z)
string hexavigesimal = IntToString(42,
Enumerable.Range('A', 26).Select(x => (char)x).ToArray());

// convert to sexagesimal
string xx = IntToString(42,
new char[] { '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'});
}

public static string IntToString(int value, char[] baseChars)
{
string result = string.Empty;
int targetBase = baseChars.Length;

do
{
result = baseChars[value % targetBase] + result;
value = value / targetBase;
}
while (value > 0);

return result;
}

/// <summary>
/// An optimized method using an array as buffer instead of
/// string concatenation. This is faster for return values having
/// a length > 1.
/// </summary>
public static string IntToStringFast(int value, char[] baseChars)
{
// 32 is the worst cast buffer size for base 2 and int.MaxValue
int i = 32;
char[] buffer = new char[i];
int targetBase= baseChars.Length;

do
{
buffer[--i] = baseChars[value % targetBase];
value = value / targetBase;
}
while (value > 0);

char[] result = new char[32 - i];
Array.Copy(buffer, i, result, 0, 32 - i);

return new string(result);
}
}
``````

### Update 2 (Performance Improvement)

Using an array buffer instead of string concatenation to build the result string gives a performance improvement especially on large number (see method `IntToStringFast`). In the best case (i.e. the longest possible input) this method is roughly three times faster. However, for 1-digit numbers (i.e. 1-digit in the target base), `IntToString` will be faster.

Tuesday, June 1, 2021

95

The point is that the interface represents a contract. A set of public methods any implementing class has to have. Technically, the interface only governs syntax, i.e. what methods are there, what arguments they get and what they return. Usually they encapsulate semantics as well, although that only by documentation.

You can then have different implementations of an interface and swap them out at will. In your example, since every pizza instance is an `IPizza` you can use `IPizza` wherever you handle an instance of an unknown pizza type. Any instance whose type inherits from `IPizza` is guaranteed to be orderable, as it has an `Order()` method.

Python is not statically-typed, therefore types are kept and looked up at runtime. So you can try calling an `Order()` method on any object. The runtime is happy as long as the object has such a method and probably just shrugs and says »Meh.« if it doesn't. Not so in C#. The compiler is responsible for making the correct calls and if it just has some random `object` the compiler doesn't know yet whether the instance during runtime will have that method. From the compiler's point of view it's invalid since it cannot verify it. (You can do such things with reflection or the `dynamic` keyword, but that's going a bit far right now, I guess.)

Also note that an interface in the usual sense does not necessarily have to be a C# `interface`, it could be an abstract class as well or even a normal class (which can come in handy if all subclasses need to share some common code – in most cases, however, `interface` suffices).

Sunday, June 6, 2021

95

That was kind of an interesting question, so I went a little overboard:

``````class Integer
def to_base(base=10)
return  if zero?
raise ArgumentError, 'base must be greater than zero' unless base > 0
num = abs
return  * num if base == 1
[].tap do |digits|
while num > 0
digits.unshift num % base
num /= base
end
end
end
end
``````

This works for arbitrary bases. It only works for integers, although there is no reason why it couldn't be extended to work with any arbitrary number. Also, it ignores the sign of the number. Again, there is no reason why it must do that, but mainly I didn't want to have to come up with a convention for returning the sign in the return value.

``````class Integer
old_to_s = instance_method(:to_s)
define_method :to_s do |base=10, mapping=nil, sep=''|
return old_to_s.bind(self).(base) unless mapping || base > 36
mapping ||= '0123456789abcdefghijklmnopqrstuvwxyz'
end
end

[Fixnum, Bignum].each do |klass|
old_to_s = klass.instance_method(:to_s)
klass.send :define_method, :to_s do |base=10, mapping=nil, sep=''|
return old_to_s.bind(self).(base) unless mapping || base > 36
return super(base, mapping, sep) if mapping
return super(base)
end
end
``````

I also extended the `to_s` method so that it works with bases greater than 36. If you want to use a base greater than 36, you have to pass in a mapping object which maps the "digits" to strings. (Well, actually, all that is required is that you provide an object that responds to `[]` and returns something which responds to `to_s`. So, a string is perfect, but e.g. an array of integers also works.)

It also accepts an optional separator, which is used to separate the digits.

For example, this allows you to format an IPv4 address by treating it as a base-256 number and using the identity for the mapping and `'.'` as the separator:

``````2_078_934_278.to_s(256, Array.new(256) {|i| i }, '.') # => '123.234.5.6'
``````

Here's an (incomplete) testsuite:

``````require 'test/unit'
class TestBaseConversion < Test::Unit::TestCase
def test_that_83992_in_base_85_is_11_53_12
assert_equal [11, 53, 12], 83992.to_base(85)
end
def test_that_83992_in_base_37_is_1_24_13_2
assert_equal [1, 24, 13, 2], 83992.to_base(37)
end
def test_that_84026_in_base_37_is_1_24_13_36
assert_equal [1, 24, 13, 36], 84026.to_base(37)
end
def test_that_0_in_any_base_is_0
100.times do |base|
assert_equal , 0.to_base(base)
assert_equal , 0.to_base(1 << base)
assert_equal , 0.to_base(base << base)
end
end
def test_that_84026_in_base_37_prints_1od_
assert_equal '1od_', 84026.to_s(37, '0123456789abcdefghijklmnopqrstuvwxyz_')
end
assert_equal '123.234.5.6', addr.to_s(256, Array.new(256) {|i| i}, '.')
end
def test_that_old_to_s_still_works
assert_equal '84026', 84026.to_s
assert_equal '1su2', 84026.to_s(36)
end
end
``````
Friday, July 30, 2021

89

You can ensure all requests have these query parameters by adding a custom RequestInterceptor to your RestAdapter

``````RequestInterceptor requestInterceptor = new RequestInterceptor()
{
@Override
}
};

``````
Monday, August 9, 2021

17

I am not sure what you want to achieve but the following compiles and runs without exceptions:

``````class Program
{
static void Main(string[] args)
{
var holder = new Holder<IObject>();
holder.MyItem = new Object { List = new List<IObject>() };
holder.ChangeItemList(new Object { List = new List<IObject>() });
}
}

public class Object : IObject
{
public List<IObject> List { get; set; }
}

public interface IObject
{
List<IObject> List { get; set; }
}

public class Holder<T> where T : IObject
{
public T MyItem { get; set; }

public void ChangeItemList(T item)
{
MyItem.List = item.List;
}
}
``````
Friday, September 3, 2021