C#中值类型BigInteger的限制是多少?

如MSDN中所描述的BigInteger是:

表示任意大整数的不可变类型,其理论上的值没有上限或下限。

我可以看到BigInteger是一个ValueType ,据我所知,ValueType的最大大小必须为16个字节

MSDN进一步说:

对于导致BigInteger值过大的任何操作,都可以抛出OutOfMemoryException。

和更多 :

尽管此过程对调用者是透明的,但它确实会导致性能下降。 在某些情况下,尤其是在非常大的BigInteger值的循环中执行重复操作时

它怎么能存储像double.MaxValue + double.MaxValue这样的大值double.MaxValue + double.MaxValue ? 我被告知它里面有ReferenceType obejects,但我在VisualStudio中定义的所有内容都是ValueTypes。

它的真正限制是什么? 即使没有,它如何“作为一种价值类型”设法存储所有数据量?

我可以看到BigInteger是一个ValueType,据我所知,ValueType的最大大小必须为16个字节。

不,那不是真的。 这是一个传统的限制,但是对于值类型而言,完全可行。 例如:

 public struct Foo { private readonly int a, b, c, d, e; // Look ma, 20 bytes! } 

但是,我强烈怀疑BigInteger实际上包含对字节数组的引用:

 public struct BigInteger { private readonly byte[] data; // Some other fields... } 

( Moslem Ben Dhaou的回答显示了使用intuint[]一个当前实现,但当然有意隐藏了这个细节 。)

所以BigInteger仍然可以很小,但它可以引用一大块内存 – 如果没有足够的内存来分配执行某些操作时所需的内存,你将得到一个例外。

它怎么能存储像double这样的大值.MaxValue + double.MaxValue?

BigInteger用于整数 ,所以我不会特别想用它来做任何与double事情……但从根本上说,限制将取决于你有多少内存以及CLR可以应对的数组大小用。 实际上,在实际达到任何特定数字的限制之前,你会谈论大量的数字 – 但如果你有数量较少的数字,那显然也有很大的内存需求。

作为Jon Skeet答案的确认,我查看了BigInteger的源代码。 它实际上包含两个内部属性如下:

 internal int _sign; internal uint[] _bits; 

_bits所有私有/公共方法都使用_bits来读取/写入实际数据。

_sign用于保持BigInteger的符号。

私有方法广泛使用二元运算符和计算。 以下是类中使用的一小部分常量,可能反映了一些限制:

 private const int knMaskHighBit = -2147483648; private const uint kuMaskHighBit = 2147483648U; private const int kcbitUint = 32; private const int kcbitUlong = 64; private const int DecimalScaleFactorMask = 16711680; private const int DecimalSignMask = -2147483648; 

PS:我应该对JS回答发表评论,但是评论太短了。 要查看源代码,请下载或反编译System.Numerics.dll