当我有一个 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千兆字节之间。