当BigInteger的大小超过¼时,BigInteger的对数错误;g
本文关键字:BigInteger 错误 #188 | 更新日期: 2023-09-27 17:54:08
当我有一个BigInteger
的大小超过2gb(即¼gb;我通过试错法找到了这个阈值,对数法给出了一个错误的答案。这段简单的代码演示了:
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发送了一个bug报告。在阅读了讨论之后,我也意识到,由于BigInteger
的设计和单个对象大小的上限为2 gb, BigInteger
永远不会超过2 gb(无论您有多少内存)。因此,当BigInteher
在1/4和2 gb之间时,会发生此错误。
让我猜猜:值是
-1.3134912384757032e9
(计算对数的模小变化)?
在int
中存储并传递最高集位的索引,
8*300000000 = 2400000000 > 2147483647
所以索引绕到一个负数,即-1894967296
,和
-1894967296 * log 2 = -1.3134912384757032e9
哦。应该有人提交bug报告