2017-01-25 1 views
-3

Я немного нового в C-программирования и я немного застрял с этим вопросом:Извлечение битов в C

Предположим, что у вас есть программа C с знаковое целое число (Int) переменных х, у, г , Все переменные содержат некоторые произвольные значения. Напишите C-инструкцию, которая извлекает биты с индексом с 17 по 13 из x и помещает их как младшие значащие биты в z и извлекает наименее 3 значащих бита y и помещает их в биты с индексом 7-5 в г. Никакие другие биты z не должны быть изменены, кроме 8 бит, которые были извлечены из x и y. Примечание , что бит-индекс 0 является младшим значащим битом. Ваш ответ должен содержать один сингл C , а также короткие заметки о том, что делают разные части инструкции.

Я понимаю, что извлечение - это то же самое, что и перенос, если я не ошибаюсь.

Но мог ли кто-нибудь, пожалуйста, дать мне несколько советов о том, как решить этот вопрос?

Спасибо, вся помощь будет подтверждена!

+0

Нет, извлечение - это * не * то же, что и перенос. –

+0

Назначение имеет меньше общего с C и больше, чтобы вы понимали базовый бит-скриптинг. Вещи, о которых вам нужно узнать, это операции побитового и оперативного, побитового или операционного и побитового сдвига (слева и справа). Кроме того, сначала попробуйте сделать это на бумаге, чтобы получить его прямо там. И последний намек, попытайтесь выполнить операции по одному, и когда вы получили это правильно *, то * попробуйте сделать это в одно выражение (по одному шагу за раз). –

+0

Я не буду делать это за вас, но посмотрите на поразрядные AND '&' и побитовые OR '' 'операторы для извлечения битов и переместите их для перемещения. –

ответ

2

Извлечение бит из й:

int b = x & 0x3E000; /* x AND (...) 0011 1110 0000 0000 0000*/ 

Сдвига извлеченных бит:

b = b >> 13; /* 13 bits to the right, so that they land up starting on the first position */ 

Очистите бит от г:

z &= 0xFFFFFFE0; /* z AND 1111 1111 1111 1111 1111 1111 1110 0000 */ 

Применить биты г:

z |= b; 

Извлечение битов от у:

b = y & 0x3; /* y AND (...) 0000 0111 */ 

Сдвиг выделенных битов:

b = b << 5; /* move them 5 bits to the left so that they end up starting on position 5 */ 

Очистить биты от Z:

z &= 0xFFFFFF1F; /* z AND 1111 1111 1111 1111 1111 1111 0001 1111 */ 

Нанести биты Z:

z |= b; 

Теперь вы можете объединить "поляны" в одну операцию:

z &= 0xFFFFFF00; /* z AND 1111 1111 1111 1111 1111 1111 0000 0000 */ 

Все в одном операторе:

z = (z & 0xFFFFFF00) | ((y & 0x3) << 5) | ((x & 0x3E000) >> 13); 

Это работает для 32-битных целых чисел, или int32_t (C99 и за его пределами). С 64-битными целыми числами (int64_t) вам просто нужно использовать 0xFFFFFFFFFFFFFF00 как «очищающую маску».

Если вы используете ванильный int переменные, получить размер в битах, используя следующий:

printf("int has %ud bits\n", sizeof(int) * 8); 

sizeof() возвращает размер в байтах целого, а затем умножить результат на 8 (бит в байт в 99.999% случаев), чтобы получить размер в битах вашего целого числа, и, следовательно, размер масок, которые вы должны применить.

В общем:

  • Извлечение битов путем применения и маски, с каждым битом, установленным в 0, за исключением тех, кого вы хотите извлечь, который вы будете устанавливать 1. Причина в том, что 0 и X = 0, но 1 И X = X.
  • Сдвиг бит в нужное положение.

  • Очистить бит, применяя маску И, с каждым бит, установленным в 1, кроме тех, которые вы хотите очистить, которые вы установите на 0. Причина та же, что и выше.

  • Применить биты с помощью операции ИЛИ. Вы должны убедиться, что биты, которые вы хотите изменить в пункте назначения, установлены в 0, а те, которые вы не хотите изменять в начале координат, установлены в 0. Причина этого заключается в том, что 1 OR X = 1, но 0 OR X = X.
+0

ОП запрашивает некоторые подсказки, а не для полного решения :) –

+0

Упс! Еще раз я согрешил, не слишком внимательно прочитав вопрос. На мой взгляд, я могу сказать, что «некоторые намеки» действительно содержатся в полном решении. Надеюсь, я не испортил ОП. – Adrien

+0

В любом случае хороший ответ;) –

 Смежные вопросы

  • Нет связанных вопросов^_^