64-битные отрицательные целые числа в форме дополнения до двух - PullRequest
2 голосов
/ 15 февраля 2010

Я читал исходники библиотеки GNU PDF, в частности их реализацию 64-битных целых чисел. Они определили 64-разрядные целые числа как структуры из двух 32-разрядных целых чисел - более высокий порядок int подписан, а более низкий порядок int не подписан. Вот соответствующий код из заголовочного файла:

/*Definition of internal structure of the pdf_i64_t type*/
struct pdf_i64_s
{
  pdf_i32_t   high;
  pdf_u32_t low;
};

typedef struct pdf_i64_s pdf_i64_t;

Согласно руководству по архитектуре отрицательные числа представлены в виде дополнения до двух. У меня есть сомнения относительно этой функции:

[код из pdf-types.c ]

void pdf_i64_assign_quick (pdf_i64_t *bignum,
                      const pdf_i32_t value,
                  pdf_status_t *p_status)
{
  ASSIGN_SAFE(p_status, PDF_OK);

  if (bignum != NULL)
    {
      if (value < 0)
        {
          bignum->high = 0xFFFFFFFF;
        }
      else
        {
          bignum->high = 0;
        }
      bignum->low = value;
    }
  else
    {
      ASSIGN_SAFE(p_status, PDF_ERROR);
    }
}

Из того, что я прочитал, чтобы получить двоичное дополнение числа, вам нужно инвертировать все биты и добавить 1 к результату. В вышеупомянутой функции, тем не менее, для значения <0 они только устанавливают биты старшего разряда в 0xFFFFFFFF, но не изменяют биты младшего разряда вообще. Разве биты «значения» тоже не должны быть инвертированы с последующим добавлением 1? Может кто-нибудь объяснить это? </p>

Спасибо.

Ответы [ 4 ]

5 голосов
/ 15 февраля 2010

Вы заметите, что value это уже 32-разрядное целое число со знаком - если оно отрицательное, оно уже соответствующим образом инвертировано. Все, что нужно сделать, это расширение знака.

3 голосов
/ 15 февраля 2010

Я думаю, что вы смешиваете несколько вещей - чтобы свести на нет число в двоичной записи дополнения, вы переворачиваете все биты и добавляете одну.

Здесь нет отрицания. Это сохраняет значение и выполняет расширение знака - старшие биты должны быть расширены через верхние 32 бита. Это то, что происходит, поскольку вход уже подписан, два дополнения ввода.

1 голос
/ 15 февраля 2010

Анон уже ответил на это, я просто хотел опубликовать небольшую оптимизацию, которая делает то же самое без ветвления.

void pdf_i64_assign_quick (pdf_i64_t *bignum,
                      const pdf_i32_t value,
                  pdf_status_t *p_status)
{
  ASSIGN_SAFE(p_status, PDF_OK);

  if (bignum != NULL)
    {
      bignum->high = (value >= 0) - 1;
      bignum->low = value;
    }
  else
    {
      ASSIGN_SAFE(p_status, PDF_ERROR);
    }
}

0xffffffff - это 32-битный шестнадцатеричный код для -1, а (значение> = 0) оценивается как 1 или 0, поэтому он также устанавливает высокий уровень в 0xffffffff для отрицательных значений value и в 0 для положительных значений.

0 голосов
/ 15 февраля 2010

Там написано, что значение является 32-битным целым ... значение уже будет в форме дополнения 2 с, поэтому не нужно менять

...