Crikey. Хорошо, во-первых, как реализованы bignums: в GMP и в других библиотеках обычно поле фиксированной ширины обозначается как «конечность» или часть числа. Вы до сих пор правильно поняли эту часть, за исключением того, что вы с большей вероятностью будете использовать uint32_t
или uint64_t
для 32- и 64-битных платформ соответственно, потому что это размер регистров и инструкции, такие как adc
set a флаг переноса при добавлении двух регистров переполнения.
Во всяком случае, суть в том, что эти конечности представляют действительную величину bignum, а не его знак. Используя дополнение к двум, мы ожидаем, что где-то будет бит знака, но он становится беспорядочным, если вы хотите изменить размер числа (а adc
не заботится о подписании, он просто добавляет двоичные числа), так как вам нужно найти старый знак немного, извлеки это, запомни это, и оно вернулось в нужное место ... очень медленно.
Я не уверен, чего вы пытаетесь добиться, инвертируя биты в каждой конечности. Если вы представляете себе такой набор конечностей (сокращение от простоты)
1011 0111 1010 1011 = 47019
В итоге вы получите:
0100 1000 0101 0100 = 18516
В любом случае, GMP не представляет знак в конечностях. Целочисленный тип со знаком в GMP - mpz_t
, который определяется этой структурой:
typedef struct
{
int _mp_alloc; /* Number of *limbs* allocated and pointed
to by the _mp_d field. */
int _mp_size; /* abs(_mp_size) is the number of limbs the
last field points to. If _mp_size is
negative this is a negative number. */
mp_limb_t *_mp_d; /* Pointer to the limbs. */
} __mpz_struct;
typedef __mpz_struct mpz_t[1];
Итак, как вы можете видеть, _mp_size
- это то, как GMP представляет числа со знаком.
В коде (в частности, mpz/aors.h
) вы увидите, что используется:
usize = u->_mp_size;
vsize = VARIATION v->_mp_size;
// .....
if ((usize ^ vsize) < 0)
{
/* U and V have different sign. Need to compare them to determine
which operand to subtract from which. */
// does subtraction instead of add.
Фактические операции выполняются серией функций mpn_
, которые относятся к вашим типам без знака.
GMP имеет ряд функций импорта / экспорта из базовых типов, которые должны позволять вам правильно устанавливать размер. Я не совсем уверен, что вы пытаетесь сделать, но, если их недостаточно, вы должны быть в состоянии установить это самостоятельно.