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#?
FAST "FROM" AND "TO" METHODS
I am late to the party, but I compounded previous answers and improved over them. I think these two methods are faster than any others posted so far. I was able to convert 1,000,000 numbers from and to base 36 in under 400ms in a single core machine.
Example below is for base 62. Change the
BaseChars
array to convert from and to any other base.EDIT (2018-07-12)
Fixed to address the corner case found by @AdrianBotor (see comments) converting 46655 to base 36. This is caused by a small floating-point error calculating
Math.Log(46656, 36)
which is exactly 3, but .NET returns3 + 4.44e-16
, which causes an extra character in the output buffer.I had a similar need, except I needed to do math on the "numbers" as well. I took some of the suggestions here and created a class that will do all this fun stuff. It allows for any unicode character to be used to represent a number and it works with decimals too.
This class is pretty easy to use. Just create a number as a type of
New BaseNumber
, set a few properties, and your off. The routines take care of switching between base 10 and base x automatically and the value you set is preserved in the base you set it in, so no accuracy is lost (until conversion that is, but even then precision loss should be very minimal since this routine usesDouble
andLong
where ever possible).I can't command on the speed of this routine. It is probably quite slow, so I'm not sure if it will suit the needs of the one who asked the question, but it certain is flexible, so hopefully someone else can use this.
For anyone else that may need this code for calculating the next column in Excel, I will include the looping code I used that leverages this class.
And now for the code to loop through Excel columns:
You'll note the important part of the Excel part is that 0 is identified by a @ in the re-based number. So I just filter out all the numbers that have an @ in them and I get the proper sequence (A, B, C, ..., Z, AA, AB, AC, ...).
I recently blogged about this. My implementation does not use any string operations during the calculations, which makes it very fast. Conversion to any numeral system with base from 2 to 36 is supported:
I've also implemented a fast inverse function in case anyone needs it too: Arbitrary to Decimal Numeral System.
I too was looking for a fast way to convert decimal number to another base in the range of [2..36] so I developed the following code. Its simple to follow and uses a Stringbuilder object as a proxy for a character buffer that we can index character by character. The code appears to be very fast compared to alternatives and a lot faster than initialising individual characters in a character array.
For your own use you might prefer to: 1/ Return a blank string rather than throw an exception. 2/ remove the radix check to make the method run even faster 3/ Initialise the Stringbuilder object with 32 '0's and remove the the line result.Remove( 0, i );. This will cause the string to be returned with leading zeros and further increase the speed. 4/ Make the Stringbuilder object a static field within the class so no matter how many times the DecimalToBase method is called the Stringbuilder object is only initialised the once. If you do this change 3 above would no longer work.
I hope someone finds this useful :)
AtomicParadox
One can also use slightly modified version of the accepted one and adjust base characters string to it's needs: