Самый быстрый способ преобразовать основу 10 чисел в основу в.NET?

Еще один способ проверить, что меня одурачили, - оставил ли ты ожидающий код заполнителя на месте (opps):

ScenarioContext.Current.Pending();

пометит тест как не реализованный.

103
задан Community 23 May 2017 в 12:26
поделиться

2 ответа

Convert.ToString может использоваться для преобразования числа в его эквивалентное строковое представление с указанным основанием.

Пример:

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

Однако, как указано в комментариях, Convert.ToString поддерживает только следующий ограниченный - но обычно достаточный - набор баз: 2, 8, 10 или 16.

Обновление (для удовлетворения требований преобразования в любую базу):

Я не знаю ни одного метода в BCL, который мог бы преобразовывать числа в любую базу, поэтому вам пришлось бы написать свою собственную небольшую служебную функцию. Простой пример будет выглядеть так (обратите внимание, что это, безусловно, можно сделать быстрее, заменив конкатенацию строк):

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

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

Обновление 2 (Улучшение производительности)

Использование буфера массива вместо конкатенации строк для построения результирующей строки дает улучшение производительности, особенно для большого числа (см. Метод IntToStringFast ). В лучшем случае (т. Е. При максимально возможной длине ввода) этот метод работает примерно в три раза быстрее. Однако для 1-значных чисел (т. Е. 1-значных в целевой базе) IntToString будет быстрее.

127
ответ дан 24 November 2019 в 04:18
поделиться

Could this class from this forum post help you?

public class BaseConverter { 

public static string ToBase(string number, int start_base, int target_base) { 

  int base10 = this.ToBase10(number, start_base); 
  string rtn = this.FromBase10(base10, target_base); 
  return rtn; 

} 

public static int ToBase10(string number, int start_base) { 

  if (start_base < 2 || start_base > 36) return 0; 
  if (start_base == 10) return Convert.ToInt32(number); 

  char[] chrs = number.ToCharArray(); 
  int m = chrs.Length - 1; 
  int n = start_base; 
  int x; 
  int rtn = 0; 

  foreach(char c in chrs) { 

    if (char.IsNumber(c)) 
      x = int.Parse(c.ToString()); 
    else 
      x = Convert.ToInt32(c) - 55; 

    rtn += x * (Convert.ToInt32(Math.Pow(n, m))); 

    m--; 

  } 

  return rtn; 

} 

public static string FromBase10(int number, int target_base) { 

  if (target_base < 2 || target_base > 36) return ""; 
  if (target_base == 10) return number.ToString(); 

  int n = target_base; 
  int q = number; 
  int r; 
  string rtn = ""; 

  while (q >= n) { 

    r = q % n; 
    q = q / n; 

    if (r < 10) 
      rtn = r.ToString() + rtn; 
    else 
      rtn = Convert.ToChar(r + 55).ToString() + rtn; 

  } 

  if (q < 10) 
    rtn = q.ToString() + rtn; 
  else 
    rtn = Convert.ToChar(q + 55).ToString() + rtn; 

  return rtn; 

} 

}

Totally untested... let me know if it works! (Copy-pasted it in case the forum post goes away or something...)

2
ответ дан 24 November 2019 в 04:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: