11

サイズがBigInteger2 ギガビット (1/4 ギガバイトです。このしきい値は試行錯誤で見つけました) を超える場合、対数法では間違った答えが返されます。この単純なコードは次のことを示しています。

  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の間の数値に対しては負の対数が必要です(整数はありません)。私の数値以上は、慣例により、最上位バイトが と の間である場合、正の を意味するため、 より大きいです。01i1i210127BigInteger

のドキュメントを読むとBigInteger.Log、対数が「Double データ型の範囲外」の場合にスローされる可能性があると主張しています。明らかに、それにはバイト数を超えるメモリストレージを備えたコンピューターが必要1E+300であり、観測可能な宇宙は小さすぎてそのようなコンピューターを含めることはできないため、それは決して起こらないと思います.

では、なぜこれが機能しないのでしょうか。

PS!サイズ オーバー2 ^^ 31ビットは、 の実際の値BigIntegerが オーバー2 ^^ (2 ^^ 31)、またはおよそであることを意味しcirca 8.8E+646456992ます。


更新: Microsoft Connect にバグ レポートを送信しました。議論を読んだ後、 の設計とBigInteger1 つのオブジェクトのサイズの上限が 2 ギガバイトであるため、aBigIntegerが 2 ギガバイトを超えることはあり得ないことにも気付きました (メモリの量に関係なく)。したがって、このバグBigInteherは が ¼ から 2 ギガバイトの間にある場合に発生します。

4

1 に答える 1

11

推測させてください:値は

-1.3134912384757032e9

(対数の計算におけるモジュロ小さな変動)?

設定された最上位ビットのインデックスが格納され、 に渡されますint

8*300000000 = 2400000000 > 2147483647

したがって、インデックスは負の数、つまり-1894967296にラップアラウンドし、

-1894967296 * log 2 = -1.3134912384757032e9

おっとっと。誰かがバグレポートを提出する必要があります。

于 2013-01-18T17:09:43.690 に答える