Переключение между двумя регистрами в C - PullRequest
0 голосов
/ 27 февраля 2012

У меня есть два 32-разрядных целых числа HI & LO, и мне нужно сдвинуть в них биты вправо, чтобы последний последний бит HI стал самым значимым битом LO.Другими словами, операция сдвига должна работать, как если бы два бита были одной 64-битной единицей.Язык C / C ++
Спасибо!

Ответы [ 3 ]

1 голос
/ 28 февраля 2012

Если ваш C имеет тип long long (64-битный), то лучше использовать это, но если вам нужно сделать это в две половины, это будет выглядеть так для логического сдвига

LO = HI & 1 ? ( LO >> 1 ) | 0x80000000 : ( LO >> 1) & 0x7FFFFFFF;
HI = ( HI >> 1 ) & 0x7FFFFFFF;

Результат смещения вправо отрицательного числа зависит от платформы, на которой вы работаете: он может расширять или не расширять знаковый бит.Этот код обслуживает любую возможность.

1 голос
/ 28 февраля 2012

Если ваш компилятор поддерживает тип long long (то есть 64-битные целые числа), вы можете сделать следующее:

unsigned long long joined = (((unsigned long long)hi) << 32) | lo;
joined >>= 1;
uint32_t new_low = (uint32_t)joined;

Любой приличный компилятор распознает шаблон concat , который обычно не генерирует никакого кода. Сдвиг будет генерировать более или менее оптимальную последовательность, и окончательное приведение, как правило, также не будет генерировать какой-либо код.

1 голос
/ 27 февраля 2012

Этот код ниже сдвигает вправо на 1 бит, как вы описали.

Он работает, маскируя все, кроме самого младшего бита в hi, и сдвигая его полностью влево (самый значимый бит), и соединяя его с lo, сдвинутым вправо на один бит.

Затем он просто сдвигает hi на один бит вправо.

{
    lo = ((hi & 0x00000001)<<31) | (lo >> 1);
    hi = hi >> 1;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...