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

后端 未结 12 1229
予麋鹿
予麋鹿 2020-11-22 04:07

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);

12条回答
  •  感情败类
    2020-11-22 04:32

    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' });
    
            // convert to hexadecimal
            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;
        }
    
        /// 
        /// An optimized method using an array as buffer instead of 
        /// string concatenation. This is faster for return values having 
        /// a length > 1.
        /// 
        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.

提交回复
热议问题