2009-03-26 15 views
5

Est-ce que .NET a une fonction native qui est équivalente à base_convert de PHP ou devrais-je écrire le mien? Je veux convertir de n'importe quelle base à n'importe quelle autre base - où la base 'à' ou la base 'de' peut être n'importe quel entier 2-36.base_convert dans .NET

Exemple de la fonction PHP: base_convert ($ number_to_convert, $ from_base, $ to_base)

// convert 101 from binary to decimal 
echo base_convert('101', 2, 10); 
// 5 

Comme indiqué par Luc dans les commentaires de la réponse de Jon Skeet: Convert.ToString ne peut pas gérer la conversion en/à partir de toute base arbitraire, seulement 2, 8, 10 et 16

Mise à jour: Apparemment, la réponse est: non, il n'y a pas de manière native. Ci-dessous, Erik montre un moyen de le faire. Une autre mise en œuvre est ici: http://www.codeproject.com/KB/macros/Convert.aspx

Répondre

9

est ici un code qui va convertir un entier à une base arbitraire jusqu'à 36, et convertir une représentation de chaîne d'une valeur de base de x à un nombre entier (compte tenu de la base):

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 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 

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

Si vous Si vous n'êtes pas concerné par l'affichage de ces valeurs, vous pouvez utiliser des caractères étendus dans votre jeu de caractères. Si vous vous en tenez à des ascii simples, vous pouvez théoriquement avoir des valeurs base256. Au-delà de ce que je recommanderais de ne pas utiliser des caractères, mais en utilisant plutôt une autre valeur unique identifiable - bien que je ne vois pas beaucoup la valeur.

+0

N glace mais cela ne permet pas une base de départ arbitraire. Il suppose une base de départ de 10 – Dinah

+0

Ok, mis à jour pour inclure une méthode qui va convertir à partir d'une base arbitraire à une base arbitraire ... –

+0

Très agréable. Accepté! – Dinah

10

EDIT: Cette réponse est très pratique, mais ne fonctionne que pour les bases 2, 8, 10 et 16

Vous pouvez utiliser Convert.ToInt32(text, base) puis 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 
    } 
} 

Si vous convertissez vers ou à partir de la base 10, vous n'avez pas besoin de spécifier cela - c'est la valeur par défaut. Notez que cela ne fonctionne que pour les bases 2, 8, 10 et 16. Si vous voulez autre chose, vous devrez écrire votre propre analyseur/formateur.

+0

6 secondes entières. –

+0

Notez que Convert.ToInt32 et Convert.ToString ne peuvent pas gérer la conversion vers/à partir de n'importe quelle base arbitraire, seulement 2, 8, 10 et 16. – LukeH

+0

@Luke: vous venez de me battre – Dinah

1

En ConvertToBase, la ligne suivante:

while (B10> targetBase)

... devrait être:

while (B10> = targetBase)

qui prend en charge le numéro de base apparaissant dans le nombre converti (par exemple convertir "3" en base 3 donne "3" au lieu de "10").