当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的数字,我们必须有一个零对数,对于01之间的数字,我们必须有一个负对数(这里没有整数)。我上面的数字i1i21大,因为按照惯例,当最高有效字节位于0127之间时,这意味着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之间时,会发生此错误。

当BigInteger的大小超过¼时,BigInteger的对数错误;g

让我猜猜:值是

-1.3134912384757032e9

(计算对数的模小变化)?

int中存储并传递最高集位的索引,

8*300000000 = 2400000000 > 2147483647

所以索引绕到一个负数,即-1894967296,和

-1894967296 * log 2 = -1.3134912384757032e9

哦。应该有人提交bug报告