Каков предел типа значения BigInteger в C#?
как описано в MSDN BigInteger - это :
неизменяемый тип, представляющий произвольно большое целое число, теоретически ценность не имеет ни верхних, ни нижних границ.
как я вижу, BigInteger является ValueType
, насколько я знаю, ValueType должен иметь максимальный размер 16 байт.
MSDN идет дальше, говоря:
исключение OutOfMemoryException может быть вызвано для любой операции, которая вызывает Значение BigInteger слишком велико.
и еще :
хотя этот процесс прозрачен для вызывающего абонента, он вызывает производительности. В некоторых случаях, особенно при повторении операции выполняются в цикле на очень больших значений BigInteger
как он может хранить такие большие значения, как double.MaxValue + double.MaxValue
?
Мне сказали, что он имеет ReferenceType
obejects внутри него, но все, что я могу найти здесь в его определении в VisualStudio-это ValueTypes.
каков его реальный предел ? И даже если его нет, как он" как тип значения " может хранить весь этот объем данных ?
2 ответов
как я вижу, BigInteger-это ValueType, насколько я знаю, ValueType должен иметь максимальный размер 16 байтов.
нет, это неправда. Это обычных limit, но для типа значения вполне возможно взять больше, чем это. Например:
public struct Foo {
private readonly int a, b, c, d, e; // Look ma, 20 bytes!
}
однако я сильно подозреваю, что BigInteger
фактически включает ссылку на массив байтов:
public struct BigInteger {
private readonly byte[] data;
// Some other fields...
}
(мусульманский ответ Бен Дау показывает одну текущую реализацию с помощью int
и uint[]
, но, конечно,подробности из этого намеренно скрыты.)
так стоимостью of a BigInteger
все еще может быть маленьким, но он может ссылаться на большой кусок памяти - и если недостаточно памяти для выделения того, что требуется при выполнении какой-либо операции, вы получите исключение.
как он может хранить такие большие значения, как double.MaxValue + двойной.Максвеллову ?
хорошо BigInteger
на чисел, поэтому я бы не хотел использовать его для чего-либо, связанного с double
... но принципиально ограничения будут вокруг сколько памяти у вас и размер массива CLR может справиться. На самом деле, вы бы говорили о огромный числа до фактического достижения предела для любого конкретного числа-но если у вас есть газиллионы меньших чисел, это, очевидно, имеет большую память требования тоже.
в качестве подтверждения ответа от Джона Скита я посмотрел на исходный код BigInteger
. На самом деле он содержит два внутренних свойства:
internal int _sign;
internal uint[] _bits;
_bits
используется почти всеми частными / общедоступными методами в классе, которые используются для чтения/записи фактических данных.
_sign
используется для сохранения знака BigInteger
.
частные методы широко используют двоичные операторы и вычисления. Вот небольшой список констант используется в классе, который может немного отражать ограничения:
private const int knMaskHighBit = -2147483648;
private const uint kuMaskHighBit = 2147483648U;
private const int kcbitUint = 32;
private const int kcbitUlong = 64;
private const int DecimalScaleFactorMask = 16711680;
private const int DecimalSignMask = -2147483648;
PS: Я должен был прокомментировать J. S. ответ, но комментарий слишком короткий. Чтобы просмотреть исходный код, либо скачать декомпилировать System.Numerics.dll
.