.NET将非常大的数字转换为不同的数字基数

时间:2013-05-17 10:55:24

标签: c# largenumber number-systems

有没有办法将非常大的二进制,十进制和十六进制数转换成彼此? 我必须使用它来模拟高达256位的寻址过程。

我想进行以下转换(如果可能的话,将它们存储在一个对象中)

  

非常大的二进制数 - >非常大的十进制数

     

非常大的二进制数 - >非常大的十六进制数

     

非常大的十进制数 - >非常大的二进制数

     

非常大的十进制数 - >非常大的十六进制数

     

非常大的十六进制数 - >非常大的二进制数

     

非常大的十六进制数 - >非常大的十进制数

     

非常大的二进制数 - >串

     

非常大的十进制数 - >串

     

非常大的十六进制数 - >串

分割和连接非常大的二进制数的可能性非常重要。 如果可能的话,我会使用类支持的解决方案,并使用byte []类型避免从一个数字库到另一个数字库的手动转换。

我已经尝试过BigInteger类,它可以存储非常大的数字,但不能将它们转换为另一个数字基础。

2 个答案:

答案 0 :(得分:0)

Andrew Jonkers的解决方案:

//Convert number in string representation from base:from to base:to. 
//Return result as a string
public static String Convert(int from, int to, String s)
{
    //Return error if input is empty
    if (String.IsNullOrEmpty(s))
    {
        return ("Error: Nothing in Input String");
    }
    //only allow uppercase input characters in string
    s = s.ToUpper();

    //only do base 2 to base 36 (digit represented by characters 0-Z)"
    if (from < 2 || from > 36 || to < 2 || to > 36) 
    { return ("Base requested outside range"); }

    //convert string to an array of integer digits representing number in base:from
    int il = s.Length;
    int[] fs = new int[il];
    int k = 0;
    for (int i = s.Length - 1; i >= 0; i--)
    {
        if (s[i] >= '0' && s[i] <= '9') { fs[k++] = (int)(s[i] - '0'); }
        else
        {
            if (s[i] >= 'A' && s[i] <= 'Z') { fs[k++] = 10 + (int)(s[i] - 'A'); }
            else
            { return ("Error: Input string must only contain any of 0-9 or A-Z"); } //only allow 0-9 A-Z characters
        }
    }

    //check the input for digits that exceed the allowable for base:from
    foreach(int i in fs)
    {
        if (i >= from) { return ("Error: Not a valid number for this input base"); }
    }

    //find how many digits the output needs
    int ol = il * (from / to+1);
    int[] ts = new int[ol+10]; //assign accumulation array
    int[] cums = new int[ol+10]; //assign the result array
    ts[0] = 1; //initialize array with number 1 

    //evaluate the output
    for (int i = 0; i < il; i++) //for each input digit
    {
        for (int j = 0; j < ol; j++) //add the input digit 
            // times (base:to from^i) to the output cumulator
        {
            cums[j] += ts[j] * fs[i];
            int temp = cums[j];
            int rem = 0;
            int ip = j;
            do // fix up any remainders in base:to
            {
                rem = temp / to;
                cums[ip] = temp-rem*to; ip++;
                cums[ip] += rem;
                temp = cums[ip];
            }
            while (temp >=to);
        }

        //calculate the next power from^i) in base:to format
        for (int j = 0; j < ol; j++)
        {
            ts[j] = ts[j] * from;
        } 
        for(int j=0;j<ol;j++) //check for any remainders
        {
            int temp = ts[j];
            int rem = 0;
            int ip = j;
            do  //fix up any remainders
            {
                rem = temp / to;
                ts[ip] = temp - rem * to; ip++;
                ts[ip] += rem;
                temp = ts[ip];
            }
            while (temp >= to);
        }
    }

    //convert the output to string format (digits 0,to-1 converted to 0-Z characters) 
    String sout = String.Empty; //initialize output string
    bool first = false; //leading zero flag
    for (int i = ol ; i >= 0; i--)
    {
        if (cums[i] != 0) { first = true; }
        if (!first) { continue; }
        if (cums[i] < 10) { sout += (char)(cums[i] + '0'); }
        else { sout += (char)(cums[i] + 'A'-10); }
    }
    if (String.IsNullOrEmpty(sout)) { return "0"; } //input was zero, return 0
    //return the converted string
    return sout;
}

答案 1 :(得分:0)

我曾经遇到过同样的问题。我编写了简单的方法,将十进制数组的数组更改为二进制数组。

 private int[] ConvertDecimalCharArrayToBinaryCharArray(int[] decimalValues)
    {
        List<int> result = new List<int>();
        bool end = false;
        while (end == false)
        {
            result.Add(decimalValues[decimalValues.Length - 1] % 2);

            int previous = 0;
            bool allzeros = true;
            for (int i = 0; i < decimalValues.Length; i++)
            {

                var x = decimalValues[i];
                if (x != 0)
                {
                    allzeros = false;
                }

                if (allzeros && i == decimalValues.Length - 1)
                {
                    end = true;
                }
                var a = (x + previous) / 2;
                if ((x + previous) % 2== 1)
                {
                    previous = 10;
                }
                else
                {
                    previous = 0;
                }
                decimalValues[i] = a;
            }
        }

        result.RemoveAt(result.Count - 1);
        result.Reverse();
        return result.ToArray();
    }