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
будет быстрее.
Я недавно писал об этом в блоге . Моя реализация не использует никаких строковых операций во время вычислений, что делает ее очень быстрой . Поддерживается преобразование в любую систему счисления с основанием от 2 до 36:
Я также реализовал быструю обратную функцию на случай, если она кому-то тоже понадобится: от произвольной до десятичной системы счисления .
источник
result = "-" + result
? Это что-то вроде обивки? Как я могу изменить код, чтобы использовать только AZ или 0-9 для символа заполнения?"-"
Вresult = "-" + result
стендах для отрицательного знака отрицательных чисел. Это не символ заполнения.БЫСТРЫЕ МЕТОДЫ " ОТ " И " ДО "
Я опаздываю на вечеринку, но я обобщил предыдущие ответы и улучшил их. Я думаю, что эти два метода быстрее, чем любые другие опубликованные на данный момент. Я смог преобразовать 1000000 чисел из и в основание 36 менее чем за 400 мс на одноядерной машине.
Пример ниже для базы 62 . Измените
BaseChars
массив для преобразования из и в любую другую базу.РЕДАКТИРОВАТЬ (2018-07-12)
Исправлено для решения углового случая, обнаруженного @AdrianBotor (см. Комментарии) при преобразовании 46655 в основание 36. Это вызвано небольшой ошибкой с плавающей запятой при вычислении,
Math.Log(46656, 36)
которая равна точно 3, но .NET возвращает3 + 4.44e-16
, что вызывает дополнительный символ в выходном буфере .источник
BaseToLong(LongToBase(46655)) == 46655
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
и конвертируем значение46655
. Результат должен бытьZZZ
но в отладчике получаю\0ZZZ
. Только это значение становится дополнительным\0
. Например, значение46654
правильно конвертируется вZZY
.LongToBase
кreturn new string(buffer, (int) i, buffer.Length - (int)i);
Также можно использовать немного измененную версию принятой и настроить строку базовых символов под свои нужды:
источник
Очень поздно участвовать в этом, но я недавно написал следующий вспомогательный класс для работающего проекта. Он был разработан для преобразования коротких строк в числа и обратно (упрощенная идеальная хеш- функция), однако он также выполняет преобразование чисел между произвольными основаниями. Реализация
Base10ToString
метода отвечает на изначально поставленный вопрос.shouldSupportRoundTripping
Флаг передается в конструктор класса необходим , чтобы предотвратить потерю ведущих цифр из строки чисел при преобразовании в базу-10 и обратно (важно, учитывая мои требования!). В большинстве случаев потеря ведущих нулей в числовой строке, вероятно, не будет проблемой.Во всяком случае, вот код:
Его также можно разделить на подклассы для получения пользовательских преобразователей чисел:
И код будет использоваться так:
источник
Может ли вам помочь этот класс из этого сообщения на форуме ?
Совершенно непроверено ... дайте мне знать, если это работает! (Скопируйте его на случай, если сообщение на форуме исчезнет или что-то в этом роде ...)
источник
Я тоже искал быстрый способ преобразования десятичного числа в другое основание в диапазоне [2..36], поэтому я разработал следующий код. Он прост в использовании и использует объект Stringbuilder в качестве прокси для символьного буфера, который мы можем индексировать символ за символом. Код кажется очень быстрым по сравнению с альтернативами и намного быстрее, чем инициализация отдельных символов в массиве символов.
Для собственного использования вы можете предпочесть: 1 / Вернуть пустую строку, а не генерировать исключение. 2 / удалите проверку системы счисления, чтобы метод работал еще быстрее 3 / Инициализируйте объект Stringbuilder с 32 '0 и удалите результат строки. Remove (0, i) ;. Это приведет к тому, что строка будет возвращена с ведущими нулями и еще больше увеличит скорость. 4 / Сделайте объект Stringbuilder статическим полем внутри класса, поэтому независимо от того, сколько раз вызывается метод DecimalToBase, объект Stringbuilder инициализируется только один раз. Если вы сделаете это, изменение 3 выше больше не будет работать.
Надеюсь, кому-то это пригодится :)
АтомныйПарадокс
источник
Я использовал это, чтобы сохранить Guid как более короткую строку (но ограничивался использованием 106 символов). Если кому-то интересно, вот мой код для декодирования строки обратно в числовое значение (в этом случае я использовал 2 ulong для значения Guid, а не кодировал Int128 (так как я в 3.5, а не в 4.0). Для ясности CODE - это string const с уникальными символами 106. ConvertLongsToBytes довольно неинтересный.
источник
У меня была аналогичная потребность, за исключением того, что мне также нужно было заниматься математикой с «числами». Я воспользовался некоторыми предложениями и создал класс, который будет делать все эти забавные вещи. Он позволяет использовать любой символ Юникода для представления числа, а также работает с десятичными знаками.
Этот класс довольно прост в использовании. Просто создайте число как тип
New BaseNumber
, установите несколько свойств и выключите. Подпрограммы заботятся о переключении между базой 10 и базой x автоматически, а значение, которое вы установили, сохраняется в базе, в которой вы его установили, поэтому точность не теряется (до преобразования, но даже тогда потеря точности должна быть очень минимальной, поскольку это рутинное использованиеDouble
иLong
везде, где это возможно).Я не могу управлять скоростью этой рутины. Вероятно, это довольно медленно, поэтому я не уверен, подойдет ли он потребностям того, кто задал вопрос, но он определенно гибкий, поэтому, надеюсь, кто-то другой сможет это использовать.
Для всех, кому может понадобиться этот код для вычисления следующего столбца в Excel, я добавлю код цикла, который я использовал, который использует этот класс.
А теперь код для циклического перебора столбцов Excel:
Вы заметите, что важной частью Excel является то, что 0 обозначается символом @ в пересчитанном числе. Поэтому я просто отфильтровываю все числа, в которых есть @, и получаю правильную последовательность (A, B, C, ..., Z, AA, AB, AC, ...).
источник
источник
Если кто-то ищет вариант VB, это было основано на ответе Павла:
источник
Это довольно простой способ сделать это, но он может быть не самым быстрым. Он довольно мощный, потому что его можно компоновать.
Объедините это с этим простым методом расширения, и теперь возможно получение любой базы:
Его можно использовать так:
Результат:
источник