base_convert в.NET
Есть ли в.NET встроенная функция, эквивалентная PHP http://php.net/base_convert, или мне нужно написать свою собственную? Я хочу преобразовать из любой базы в любую другую базу - где база "to" или база "from" может быть любым целым числом 2-36.
Пример функции PHP: base_convert($number_to_convert, $from_base, $to_base)
// convert 101 from binary to decimal
echo base_convert('101', 2, 10);
// 5
Как отметил Люк в комментариях к ответу Джона Скита: Convert.ToString не может обработать преобразование в / из произвольной базы, только 2, 8, 10 и 16
Обновление: Судя по всему, ответ: нет, родного пути нет. Ниже Эрик показывает один из способов сделать это. Другая реализация находится здесь: http://www.codeproject.com/KB/macros/Convert.aspx
3 ответа
Вот некоторый код, который преобразует целое число в произвольное основание до 36 и преобразует строковое представление значения базового x в целое число (с учетом основания):
class Program {
static void Main(string[] args) {
int b10 = 123;
int targetBase = 5;
string converted = ConvertToBase(b10, targetBase);
int convertedBack = ConvertFromBase(converted, targetBase);
string base3 = "212210";
string base7 = ConvertFromBaseToBase(base3, 3, 7);
Console.WriteLine(converted);
Console.WriteLine(convertedBack);
Console.WriteLine(base7);
Console.ReadLine();
}
private const string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static string ConvertToBase(int b10, int targetBase) {
if (targetBase < 2) throw new ArgumentException("Target base must be greater than 2.", "targetBase");
if (targetBase > 36) throw new ArgumentException("Target base must be less than 36.", "targetBase");
if (targetBase == 10) return b10.ToString();
StringBuilder result = new StringBuilder();
while (b10 >= targetBase) {
int mod = b10 % targetBase;
result.Append(chars[mod]);
b10 = b10 / targetBase;
}
result.Append(chars[b10]);
return Reverse(result.ToString());
}
private static int ConvertFromBase(string bx, int fromBase) {
if (fromBase < 2) throw new ArgumentException("Base must be greater than 2.", "fromBase");
if (fromBase > 36) throw new ArgumentException("Base must be less than 36.", "fromBase");
if (fromBase == 10) return int.Parse(bx);
bx = Reverse(bx);
int acc = 0;
for (int i = 0; i < bx.Length; i++) {
int charValue = chars.IndexOf(bx[i]);
acc += (int)Math.Pow(fromBase, i) * charValue;
}
return acc;
}
public static string ConvertFromBaseToBase(string bx, int fromBase, int toBase) {
int b10 = ConvertFromBase(bx, fromBase);
return ConvertToBase(b10, toBase);
}
public static string Reverse(string s) {
char[] charArray = new char[s.Length];
int len = s.Length - 1;
for (int i = 0; i <= len; i++)
charArray[i] = s[len - i];
return new string(charArray);
}
}
Если вы не заинтересованы в отображении этих значений, вы можете использовать расширенные символы в наборе символов - если вы придерживаетесь простого ascii, теоретически вы можете иметь значения base256. Выходя за рамки этого, я бы порекомендовал не использовать символы, а вместо этого использовать какое-то другое уникально идентифицируемое значение - хотя я не очень вижу значение.
РЕДАКТИРОВАТЬ: Этот ответ очень удобен, но работает только для основ 2, 8, 10 и 16
Ты можешь использовать Convert.ToInt32(text, base)
а потом Convert.ToString(number, base)
:
using System;
class Test
{
static void Main()
{
int number = Convert.ToInt32("101", 2);
string text = Convert.ToString(number, 10);
Console.WriteLine(text); // Prints 5
}
}
Если вы конвертируете в или из базы 10, вам не нужно указывать это - это значение по умолчанию.
Обратите внимание, что это работает только для баз 2, 8, 10 и 16. Если вам нужно что-то еще, вам придется написать свой собственный анализатор / форматтер.
В ConvertToBase следующая строка:
while (b10> targetBase)
...должно быть:
while (b10> = targetBase)
Который заботится о появлении базового числа в преобразованном числе (например, преобразование "3" в основание 3 дает "3" вместо "10").