2009-03-26 8 views
5

Hat .NET eine native Funktion, die PHP base_convert entspricht oder muss ich meine eigene schreiben? Ich möchte von jeder Basis zu jeder anderen Basis konvertieren - wobei entweder die 'zu' Basis oder die 'von' Basis eine ganze Zahl von 2 bis 36 sein kann.base_convert in .NET

Beispiel der PHP-Funktion: base_convert ($ number_to_convert, $ from_base, $ to_base)

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

Wie in den Kommentaren der Antwort Jon Skeet von Luke bemerkt: Convert.ToString nicht umgehen kann Umstellung auf/von jeder beliebigen Basis, nur 2, 8, 10 und 16

Update: Offenbar ist die Antwort: Nein, es gibt keinen nativen Weg. Unten zeigt Erik einen Weg, dies zu tun. Eine weitere Implementierung ist hier: http://www.codeproject.com/KB/macros/Convert.aspx

Antwort

9

Hier einige Code, der eine ganze Zahl zu einer beliebigen Basis 36 bis umwandeln werden, und eine String-Darstellung eines Basis x-Wert auf eine ganze Zahl (angesichts der Basis) konvertieren:

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

Wenn Sie‘ Unabhängig von der Anzeige dieser Werte können Sie erweiterte Zeichen in Ihrem Zeichensatz verwenden. Wenn Sie sich einfach an ascii halten, können Sie theoretisch base256-Werte haben. Darüber hinaus würde ich empfehlen, keine Zeichen zu verwenden, sondern stattdessen einen anderen, eindeutig identifizierbaren Wert zu verwenden - obwohl ich den Wert nicht viel sehe.

+0

N Eis, aber dies erlaubt keine willkürliche Ausgangsbasis. Es nimmt eine Ausgangsbasis von 10 an. – Dinah

+0

Okay, aktualisiert, um eine Methode einzuschließen, die von einer beliebigen Basis in eine beliebige Basis umwandeln wird ... –

+0

Sehr schön. Akzeptiert! – Dinah

10

EDIT: Diese Antwort ist sehr praktisch, funktioniert aber nur für Basen 2, 8, 10 und 16

Sie Convert.ToInt32(text, base) verwenden können und dann 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 
    } 
} 

Wenn Sie zu oder von Basis 10 konvertieren, müssen Sie dies nicht angeben - es ist der Standardwert.

Beachten Sie, dass dies nur für die Basen 2, 8, 10 und 16 funktioniert. Wenn Sie noch etwas anderes möchten, müssen Sie Ihren eigenen Parser/Formatierer schreiben.

+0

6 ganze Sekunden. –

+0

Beachten Sie, dass Convert.ToInt32 und Convert.ToString keine Konvertierung zu/von jeder beliebigen Basis verarbeiten können, nur 2, 8, 10 und 16. – LukeH

+0

@Luke: Sie schlagen mich einfach – Dinah

1

In ConvertToBase, die folgende Zeile ein:

while (b10> targetBase)

... sein sollte:

while (b10> = targetBase)

Welche kümmert die Basisnummer wird in der konvertierten Zahl angezeigt (zB wenn "3" in Basis 3 konvertiert wird, ergibt sich "3" anstelle von "10").