二进制到 BigInteger 代码的 ArgumentOutOfRange 异常

ArgumentOutOfRange Exception in binary to BigInteger Code

我有这个代码:

public BigInteger getNum()
{
    BigInteger rtrnVal = 0;
    for (int a = _arr.Count; a > 0; a--)
    {
        rtrnVal = rtrnVal + (_arr[a] ? BigInteger.Pow(2, a) : 0);
    }
    return rtrnVal;
}

_arr 是一个 List<bool>。在具体测试情况下,_arr为:

1001011100001010001100101111010010101100010011000101100000101100010111101001001101010100001001000001100001010010000011001110 分别为 1 为真,0 为假。 它应该 return 12547898989848949849191494989874798798.

为什么我会收到此溢出异常?

确切地说:我在这一行收到错误:

rtrnVal = rtrnVal + (_arr[a] ? BigInteger.Pow(2, a) : 0);

编辑:这是调用它的代码:

Stopwatch st = new Stopwatch();
BigInteger x = 0;
numToBin a = new numToBin();

st.Start();

for(x = 0; x< 1000; x++)
{
    a = new numToBin(x);
    bool[] b = a.getBits();
}

long t1 = st.ElapsedMilliseconds;

st.Restart();

a = new numToBin(BigInteger.Parse("12547898989848949849191494989874798798"));
bool[] y = a.getBits();
foreach(bool z in y)
{
    Console.Write(z ? "1" : "0");
}
Console.WriteLine();

long t2 = st.ElapsedMilliseconds;

st.Restart();

a = new numToBin(y);
Console.WriteLine(a.getNum());

long t3 = st.ElapsedMilliseconds;

所以这让我认为错误出在构造函数中:

 public numToBin(BigInteger n)
 {
      _arr = new List<bool>();
      int remainder;
      while (n != 0)
      {
           remainder = (int)(n % 2);
           n = n / 2;
           _arr.Add(remainder == 1 ? true : false);
      }
 }

但即使在那里,我认为代码还可以...

Edit2:这是堆栈跟踪:

 System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
 Parameter name: index
 at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument 
 argument, ExceptionResource resource)
 at System.Collections.Generic.List`1.get_Item(Int32 index)
 at Testing_app.Program.numToBin.getNum() in 
 C:\Users\MYNAME\Source\Repos\First project\Testing app\Program.cs:line 108

我认为问题出在其他地方,因为我尝试了这段代码,它会生成比您预期的更大的数字并且工作正常:

class Program
{
    static void Main(string[] args)
    {
        Random r = new Random(1);
        bool[] _arr = new bool[1500];
        for (int i = 0; i < 1500; i++)
        {
            var x = true;//r.Next() == 1 ? true : false;
            _arr[i] = x;
        }

        BigInteger rtrnVal = 0;
        for (int a = _arr.Count() - 1; a >= 0; a--)
        {
            rtrnVal = rtrnVal + (_arr[a] ? BigInteger.Pow(2, a) : 0);
        }
        Console.WriteLine(rtrnVal);
        Console.ReadLine();
    }
}

据我所知,问题出在构造函数中,因为您正在为 for 循环内的每个操作初始化一个新列表,而没有在此处提及构造函数中的 while 循环,因此通过创建所有这些 objects。尝试简化代码并将其从构造函数中删除,因为那不是业务逻辑的地方。尝试制作一种方法来填充列表中的数据,而不是为此目的使用构造函数。并确保您没有在 for 循环的每个操作中创建新列表。在 class 的 header 中而不是在 while 循环中初始化列表。