最快的一个十进制数转换为.NET任何基本方法是什么?转换为、最快、基本、方法

2023-09-02 10:14:55 作者:萌比女汉子

我有老(ISH)C#方法,我写了,需要一个号码,将其转换为任何基础:

I have and old(ish) C# method I wrote that takes a number and converts it to any base:

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

这还不是所有的超快速,整齐。是否有.NET实现这一目标的一个良好的,已知的方式?

It's not all that super speedy and neat. Is there a good, known way of achieving this in .NET?

我在寻找的东西,让我使用任何的基地,要使用的字符的任意字符串。

I'm looking for something that allows me to use any base with an arbitrary string of characters to use.

这个只允许基地16,10,8和2:

This only allows bases 16, 10, 8 and 2:

Convert.ToString(1, x);

我想用这个来实现大规模高基数取号的优势,所有的小写和所有大写字母。就像this螺纹,但对C#没有JavaScript的。

I want to use this to achieve a massively high base taking advantage of numbers, all lower case and all upper case letters. Like in this thread, but for C# not JavaScript.

有谁知道在C#这样做的很好的,有效的方式?

Does anyone know of a good and efficient way of doing this in C#?

推荐答案

转换的ToString 可以用来将数字转换为其等效的字符串重新presentation在指定的位置。

Convert.ToString can be used to convert a number to its equivalent string representation in a specified base.

例如:

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

不过,正如指出的意见, Convert.ToString 仅支持以下有限 - 但通常就足够了 - 一套基地:2,8,10,或16

However, as pointed out by the comments, Convert.ToString only supports the following limited - but typically sufficient - set of bases: 2, 8, 10, or 16.

我不知道在BCL的任何方法,它能够为数字转换为任何基础,所以你会写自己的小的实用功能。一个简单的示例看起来像(注意通过更换字符串连接,这无疑可更快):

I'm not aware of any method in the BCL which is capable to convert numbers to any base so you would have to write your own small utility function. A simple sample would look like that (note that this surely can be made faster by replacing the string concatenation):

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

Update 2 (Performance Improvement)

Using an array buffer instead of string concatenation to build the result string gives a performance improvement especially on large number (see method IntToStringFast). In the best case (i.e. the longest possible input) this method is roughly three times faster. However, for 1-digit numbers (i.e. 1-digit in the target base), IntToString will be faster.