一尘不染

将以10为底的数字转换为.NET中任何基的最快方法?

c#

我有一个旧的(ish)C#方法,该方法接受一个数字并将其转换为任何基数:

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

并不是所有的东西都那么快速和整洁。在.NET中是否有一种良好的已知方法来实现这一目标?

我正在寻找可以使我使用 任何 带有任意字符串的基数的东西。

这仅允许以16、10、8和2为基数:

Convert.ToString(1, x);

我想利用它来利用数字,所有小写字母和所有大写字母来获得很高的基础。就像在这个线程中一样,但是对于C#来说不是JavaScript。

有谁知道在C#中执行此操作的好方法吗?


阅读 240

收藏
2020-05-19

共1个答案

一尘不染

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速度会更快。

2020-05-19