Представление числового байта C

У меня есть unsigned char vector mynumber[], представляющий bigint. Это число положительное, и я хочу преобразовать его в отрицательное число.

Я пробовал таким образом

for(int i = 0; i < dimvector;i++)
 mynumber[i] = ~mynumber[i];

Я повторяю свой вектор, но мне нужно его суммировать. Как суммировать один?

Если у меня переполнение, как решить?

Я работаю с GMP и после экспорта должен передать вектор в SHA256.

В конце я преобразовываю результат дайджеста в большое число, используя импорт (GMP).

При импорте та же проблема, что и при экспорте. Знак важен.


person Gianluca    schedule 20.06.2011    source источник
comment
Ваш код на самом деле ничего не делает, так как вы отбрасываете результат выражения ~mynumber[i].   -  person Paul R    schedule 20.06.2011
comment
я плохо пишу но проблема в другом.   -  person Gianluca    schedule 20.06.2011
comment
всегда лучше копировать и вставлять фактический код, а не вводить его приблизительно.   -  person Paul R    schedule 20.06.2011


Ответы (1)


крики. Хорошо, сначала о том, как реализованы большие числа: в 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