Неверный логарифм BigInteger, когда размер BigInteger превышает ¼ гигабайта

Когда у меня есть 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 (там нет целых чисел). Мои цифры i1 и i2 выше больше 1, поскольку, по договоренности, когда старший байт находится между 0 и 127, это означает положительный BigInteger.

Теперь, если вы прочитаете документацию для BigInteger.Log, они утверждают, что она может бросить, если логарифм "выходит за пределы диапазона Double тип данных". Теперь, очевидно, для этого потребуется компьютер с памятью размером более 1E+300 байтов, а наблюдаемый юниверс слишком мал, чтобы содержать такой компьютер, поэтому я предполагаю, что этого никогда не произойдет.

Так почему же это не работает?

PS! Размер над битами 2 ^^ 31 означает, что фактическое значение BigInteger превышает 2 ^^ (2 ^^ 31) или приблизительно circa 8.8E+646456992.


UPDATE: я отправил отчет об ошибке в Microsoft Connect. После ознакомления с обсуждениями я также осознал, что из-за дизайна BigInteger и верхнего предела в 2 гигабайта для размера одного единственного объекта BigInteger никогда не может превышать 2 гигабайта (независимо от того, сколько памяти у тебя есть). Следовательно, эта ошибка возникает, когда BigInteher находится между ¼ и 2 гигабайтами.

Ответ 1

Позвольте мне угадать: значение

-1.3134912384757032e9

(по модулю небольшие вариации при вычислении логарифма)?

Индекс самого старшего бита сохраняется и передается в int и

8*300000000 = 2400000000 > 2147483647

чтобы индекс обернулся вокруг отрицательного числа, а именно -1894967296 и

-1894967296 * log 2 = -1.3134912384757032e9

К сожалению. Кто-то должен подать отчет об ошибке.