Знаковые целые числа с произвольной точностью почти всегда реализуются с использованием представления величины знака:
- (Java) BigInteger в OpenJDK
- (Python) Bigint реализация встроенного типа Python int в CPython
- (C) mpz_t в GMP, арифметическая библиотека GNU с множественной точностью
- (C ++) BigInteger в библиотеке bigint. Автор Matt McCutchen
- (Rust) BigInt в библиотеке num-bigint
Четкое предпочтение величины знака отличается от почти универсального предпочтения дополнения до двух в целочисленных типах со знаком фиксированной ширины. Вопрос в том, почему величина знака так явно предпочтительна для BigIntegers? (Я приветствую контрпримеры, если вы не согласны с предпосылкой.)
Обратите внимание, что API BigInteger обычно определяют семантику "как если бы два дополняют" (например, Java , Python ) для побитовых операций, где это важно. Это обеспечивает соответствие с обычным значением этих операций. Это не диктует фактическое внутреннее представление (просто детали реализации), но это должно быть точкой в пользу использования внутреннего дополнения до двух, если все остальные были равны.
Числа с плавающей точкой используют величину знака, в отличие от целых чисел, которые используют дополнение до двух. Тем не менее, с плавающей точкой на самом деле это не является прецедентом, поскольку поведение и алгоритмы арифметики с плавающей точкой существенно отличаются от целочисленной арифметики. Бигнум гораздо больше похож на целые, чем на поплавки.
Мы знаем «учебник» о причинах того, почему дополнение к двум математически работает и почему оно имеет преимущества. Мне кажется, что эти причины в равной степени применимы как к int, так и к BigIntegers. Насколько это действительно так?
Существует, конечно, огромная разница между конструктивными ограничениями аппаратных целых чисел с фиксированной точностью и программными целыми числами произвольной точности. В этом смысле неудивительно, что дизайнеры сделали разные компромиссы в этих разных областях. Каковы же тогда компромиссы между величиной знака и дополнением к двум применительно к целым числам произвольной точности? Например, это может быть связано с производительностью или простотой некоторых важных алгоритмов.
Я надеюсь, что ваш ответ осветит конструктивные соображения, которые входят в арифметику BigInteger, а также поможет мне пересмотреть то, что я знаю о дополнении двух с новой точки зрения.
(Для ясности: когда я говорю, что два дополняют два для целых чисел произвольной точности, я имею в виду представление, использующее массив слов, чей битовый образец, если сложить, является представлением дополнения двух к желаемому числу - возможно, с дополнительным требованием, чтобы не было «ненужных начальных 0» (для неотрицательных чисел) или «ненужных ведущих 1» (для отрицательных чисел).)