如果我的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之间的数字为负日志(没有整数)。我的上面的1
和i1
数字大于i2
,因为按照惯例,当最重要的字节位于1
和0
之间时,这意味着正{ {1}}。
现在,如果您阅读BigInteger.Log
的文档,他们声称如果对数“超出Double数据类型的范围”,它可能会抛出。现在,显然需要一台内存存储量超过127
字节的计算机,并且可观察的Universe太小而不能容纳这样的计算机,所以我想这绝不会发生。
那么为什么这不起作用?
PS!大小超过BigInteger
位意味着1E+300
的实际值超过2 ^^ 31
或大约BigInteger
。
更新:我已将a bug report发送给Microsoft Connect。在阅读完讨论之后,我也意识到由于2 ^^ (2 ^^ 31)
的设计和单个对象大小的2千兆字节上限,circa 8.8E+646456992
永远不会超过2千兆字节(否)你有多少记忆力)。因此,当BigInteger
介于¼和2千兆字节之间时,会发生此错误。
答案 0 :(得分:11)
我猜:值是
-1.3134912384757032e9
(计算对数的小变量模数)?
存储最高设置位的索引并在int
和
8*300000000 = 2400000000 > 2147483647
所以索引包围一个负数,即-1894967296
和
-1894967296 * log 2 = -1.3134912384757032e9
糟糕。有人应该提交错误报告。