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

后端 未结 12 1383
予麋鹿
予麋鹿 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:33

    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.

    private static readonly char[] BaseChars = 
             "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToCharArray();
    private static readonly Dictionary CharValues = BaseChars
               .Select((c,i)=>new {Char=c, Index=i})
               .ToDictionary(c=>c.Char,c=>c.Index);
    
    public static string LongToBase(long value)
    {
       long targetBase = BaseChars.Length;
       // Determine exact number of characters to use.
       char[] buffer = new char[Math.Max( 
                  (int) Math.Ceiling(Math.Log(value + 1, targetBase)), 1)];
    
       var i = buffer.Length;
       do
       {
           buffer[--i] = BaseChars[value % targetBase];
           value = value / targetBase;
       }
       while (value > 0);
    
       return new string(buffer, i, buffer.Length - i);
    }
    
    public static long BaseToLong(string number) 
    { 
        char[] chrs = number.ToCharArray(); 
        int m = chrs.Length - 1; 
        int n = BaseChars.Length, x;
        long result = 0; 
        for (int i = 0; i < chrs.Length; i++)
        {
            x = CharValues[ chrs[i] ];
            result += x * (long)Math.Pow(n, m--);
        }
        return result;  
    } 
    

    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 returns 3 + 4.44e-16, which causes an extra character in the output buffer.

提交回复
热议问题