当BigInteger的大小超过¼千兆字节时,BigInteger的对数错误

Jep*_*sen 11 .net c# logarithm biginteger base-class-library

当我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
Run Code Online (Sandbox Code Playgroud)

当然,我们必须有一个数超过正数1,零日志的数量1,而负日志之间的数字01(无整数那里).按照惯例,当最高有效字节在和之间时,我的数字i1i2以上都大1于此,这意味着正数.0127BigInteger

现在,如果您阅读了文档BigInteger.Log,他们声称如果对数"超出Double数据类型的范围",它可能会抛出.现在,显然需要一台内存存储量超过1E+300字节的计算机,并且可观察的宇宙太小而不能包含这样的计算机,所以我想这绝不会发生.

那么为什么这不起作用呢?

PS!超过2 ^^ 31位的大小意味着它的实际值BigInteger超过2 ^^ (2 ^^ 31)或大约circa 8.8E+646456992.


更新:我向Microsoft Connect 发送了一个错误报告.在阅读完讨论之后,我也意识到,由于BigInteger单个对象大小的设计和2千兆字节的上限,a BigInteger永远不会超过2千兆字节(无论你有多少内存).因此,当BigInteher¼和2千兆字节之间出现此错误时.

Dan*_*her 11

让我猜一下:价值是

-1.3134912384757032e9
Run Code Online (Sandbox Code Playgroud)

(以计算对数的小变量为模)?

最高设置位的索引存储并传入int,和

8*300000000 = 2400000000 > 2147483647
Run Code Online (Sandbox Code Playgroud)

所以索引包围一个负数,即-1894967296

-1894967296 * log 2 = -1.3134912384757032e9
Run Code Online (Sandbox Code Playgroud)

哎呀.有人应该提交错误报告.

  • 实际上我认为这是设计的.您必须使用[`Array.CreateInstance`](http://msdn.microsoft.com/en-us/library/1z8w3at5.aspx)来[分配占用比`int.MaxValue`更多空间的数组](http ://stackoverflow.com/a/10946548/116614).但是,如果你使用带有长索引重载的`Array.CreateInstance`,由于[每个对象的最大大小限制],你得到一个`OutOfMemoryException`(http://stackoverflow.com/a/5791912/116614) .因此,由OP创建的数组实际上甚至不是"300,000,001"元素. (2认同)