крики. Хорошо, сначала о том, как реализованы большие числа: в GMP и других библиотеках обычно вы назначаете поле фиксированной ширины «конечностью» или частью числа. Пока вы правильно поняли эту часть, за исключением того, что вы, скорее всего, будете использовать uint32_t
или uint64_t
для 32- и 64-битных платформ соответственно, потому что это размер регистров, а такие инструкции, как adc
, устанавливают флаг переноса при добавлении двух регистров. переполняется.
В любом случае, дело в том, что эти конечности представляют реальную величину бигнума, а не его знак. Используя дополнение до двух, мы ожидаем, что где-то будет бит знака, но это становится беспорядочным, если вы хотите изменить размер числа (а 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 имеет ряд функций импорта/экспорта из основных типов, которые должны позволить вам правильно установить размер. Я не совсем уверен, что вы пытаетесь сделать, но если их недостаточно, вы должны установить это самостоятельно.
person
Community
schedule
20.06.2011
~mynumber[i]
. - person Paul R   schedule 20.06.2011