7

.NET 是否具有与 PHP 的base_convert等效的本机函数,还是我需要自己编写?我想从任何基数转换为任何其他基数——“到”基数或“从”基数可以是 2-36 的任何整数。

PHP 函数示例:base_convert($number_to_convert, $from_base, $to_base)

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

正如 Luke 在 Jon Skeet 回答的评论中指出的那样:Convert.ToString 无法处理与任意基数之间的转换,只有 2、8、10 和 16

更新:显然,答案是:不,没有原生方式。下面,Erik 展示了一种方法来做到这一点。另一个实现在这里: http: //www.codeproject.com/KB/macros/Convert.aspx

4

3 回答 3

12

编辑:这个答案非常方便,但仅适用于基数 2、8、10 和 16

您可以使用Convert.ToInt32(text, base)然后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
    }
}

如果您要转换为以 10 为基数,则无需指定 - 这是默认值。

请注意,这仅适用于基数 2、8、10 和 16。如果您需要其他任何内容,则必须编写自己的解析器/格式化程序。

于 2009-03-26T17:47:29.287 回答
10

下面是一些代码,可以将整数转换为最多 36 的任意基数,并将基数 x 值的字符串表示形式转换为整数(给定基数):

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

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

如果你不关心显示这些值,你可以在你的字符集中使用扩展字符——如果你坚持纯 ascii,理论上你可以有 base256 值。除此之外,我建议不要使用字符,而是使用其他一些唯一可识别的值——尽管我看不到它的价值。

于 2009-03-26T18:34:11.843 回答
1

在 ConvertToBase 中,以下行:

而 (b10 > targetBase)

...应该:

而 (b10 >= targetBase)

它负责在转换后的数字中弹出基数(例如,将“3”转换为基数 3 产生“3”而不是“10”)。

于 2009-07-29T15:17:31.330 回答