SORU
28 Mayıs 2009, PERŞEMBE


Hızlı herhangi bir baz 10 tabanlı bir sayı dönüştürmek için bir yol .NET?

Ben ve eski(ish) C# yazdığım yöntemi bir sayı alır ve herhangi bir baz dönüştürür:

string ConvertToBase(int number, char[] baseChars);

Tüm bu süper hızlı ve düzgün olmuyor. Elde iyi bilinen bir yolu yoktur .NET?

Beni kullanmasına izin veren bir şey arıyorumherhangi birkullanmak için karakter rasgele bir dize ile taban.

Bu sadece üsleri 16, 10, 8 ve 2 sağlar:

Convert.ToString(1, x);

Bu devasa yüksek bir üssü sayılar, küçük harf ve büyük harf yararlanarak elde etmek için kullanmak istiyorum. C this thread gibi ama# JavaScript değil.

Herkes C bunu yapmanın kolay ve etkili bir yol biliyor mu#?

CEVAP
29 Mayıs 2009, Cuma


Convert.ToString belirtilen base dize gösterimine sayıda dönüştürmek için kullanılabilir.

Örnek:

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

Yorum tarafından belirttiği gibi, ancak Convert.ToString sadece üslerine sınırlı - ama genellikle yeterli - aşağıdaki destekler: 2, 8, 10 ve 16.

Güncelleme (herhangi bir temel dönüştürmek için ihtiyacını karşılamak için):

Kendi küçük yardımcı fonksiyon yazmak zorunda böylece herhangi bir baz numaraları dönüştürmek için kapasitesine sahip KORUYUCU herhangi bir yöntem farkında değilim. Basit bir örnek (bu kesinlikle daha hızlı dize birleştirme değiştirerek yapılabilir not) gibi görünecektir:

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 (Performans Geliştirme) Güncelleyin

Dize birleştirme yerine bir dizi tampon sonuç dizesini oluşturmak için kullanılması, özellikle (yöntem IntToStringFast) çok sayıda üzerinde bir performans artışı sağlıyor. En iyi durumda (mümkün olan en uzun giriş yani) bu yöntem kabaca üç kat daha hızlı. Ancak, 1 basamaklı sayılar için (hedef üssü 1 yani basamaklı), IntToString daha hızlı olacaktır.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • CaliforniaMetin

    CaliforniaMe

    3 ŞUBAT 2013
  • Kontor.TV

    Kontor.TV

    14 Mart 2006
  • NextGenWindows

    NextGenWindo

    8 Kasım 2011