当我有一个 BigInteger
其大小超过2千兆位(即¼千兆字节;我通过反复试验找到了这个阈值),对数方法给出了错误的答案。这个简单的代码说明:
byte[] bb;
bb = new byte[150000001];
bb[150000000] = 1; // sets most significant byte to one
var i1 = new BigInteger(bb);
double log1 = BigInteger.Log(i1);
Console.WriteLine(log1); // OK, writes 831776616.671934
bb = new byte[300000001];
bb[300000000] = 1; // sets most significant byte to one
var i2 = new BigInteger(bb);
double log2 = BigInteger.Log(i2);
Console.WriteLine(log2); // Broken, gives negative number, should be twice 831776616.671934
当然,我们必须有一个超过数字的正数日志 1
,数字的零日志 1
,以及之间数字的负数日志 0
和 1
(那里没有整数)。我的号码 i1
和 i2
以上都大于 1
因为按照惯例,当最重要的字节介于两者之间时 0
和 127
,这意味着积极的 BigInteger
。
现在,如果您阅读了文档 BigInteger.Log
,他们声称,如果对数“超出Double数据类型的范围”,它可能会抛出。现在,显然需要一台内存存储量超过的计算机 1E+300
字节,可观察的宇宙太小,不能包含这样的计算机,所以我想这绝不会发生。
那么为什么这不起作用呢?
PS!大小超过 2 ^^ 31
位意味着实际值 BigInteger
结束了 2 ^^ (2 ^^ 31)
或大约 circa 8.8E+646456992
。
更新:我送了 一个错误报告 到Microsoft Connect。在阅读了讨论之后,我也意识到由于设计的原因 BigInteger
并且对于一个单个对象的大小,上限为2千兆字节 BigInteger
永远不会超过2千兆字节(无论你有多少内存)。因此,当这个错误发生时 BigInteher
介于¼和2千兆字节之间。