| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Помогите перетасовать биты. |
| Автор: =Женек= 7.4.2013, 13:41 |
| Господа, есть 16-ти битное исходное число SRC. И есть переменная DST в которую нужно переписать некоторые биты из SRC НЕ ТРОГАЯ остальные биты в DEST. А именно DST.0 - SRC.2 DST.1 - SRC.3 DST.8 - SRC.13 DST.9 - SRC.14 DST.10 - SRC.15 DST.14 - SRC.0 DST.15 - SRC.1 Как это сделать? |
| Автор: Alexeis 7.4.2013, 13:56 | ||
Объявите структуру на 16 битовых полей и манипулируйте ими как нужно
Если биты означают что-то осмысленное, то можно назвать поля по человечески. Это не самый быстрый способ, но пожалуй самый читабельный. |
| Автор: =Женек= 7.4.2013, 14:16 |
| мне нужно проще без структур - пишу для микроконтроллера. Сделал пока так: EB |=((SRC>>2) & 0x0003) | (SRC<<14) | ((SRC & 0xE000)>>5); Но биты, однажды установленные в единицу в следующий раз не обнуляются. |
| Автор: Dem_max 7.4.2013, 14:18 | ||
Код для микроконтроллеров
|
| Автор: =Женек= 7.4.2013, 14:38 |
| от вашей конструкции компилятор переклинило.... Я хотел проще, пример привел. Чисто битовые операции. |
| Автор: Alexeis 7.4.2013, 14:58 |
| Структура не отнимает нисколько памяти. Так что это не сложно, но раз без структуры, то сначала нужно очистить в DST все биты которые нужно скопировать одной маской, затем записать, например вашим способом. |
| Автор: =Женек= 7.4.2013, 15:11 | ||
| Господа, чтобы Вам понять в каком направлени двигаться приведу в пример аналогичную задачу - там 16-ти битное число нужно раскидать по двум портам напополам. И делается это так:
|
| Автор: Alexeis 7.4.2013, 15:25 | ||
|
| Автор: feodorv 7.4.2013, 15:45 |
Не нравится мне это... |
| Автор: =Женек= 7.4.2013, 16:16 |
| Спасибо, но что-то вы напутали. Если я ввожу в исходное число 0xFFFF то получаю 0b0000 0000 1000 0011, а должен получить 0b1100 0111 0000 0011 |
| Автор: Dem_max 7.4.2013, 16:17 | ||
Смени компилятор |
| Автор: =Женек= 7.4.2013, 16:29 | ||||
обязательно. Когда закончу разработку))) |
| Автор: =Женек= 7.4.2013, 17:00 | ||
Оххх.. получилось вот так:
А теперь по аналогии научите читать))) |
| Автор: =Женек= 8.4.2013, 05:13 | ||||
Вы, видимо, не знаете тонкостей роаботы с микроконтроллерами. Я уже объяснял выше, что код должен быть низкоуровневый. Не на ассемлблере, конечно, но низкоуровневый. А мне упорно шлют высший пилотаж.
зато ваш код тормозной. Ну зачем каждый раз проверять состояние бита, если его можно записать как есть? Частота контроллера всего 72 МГц, а задача - работа с дисплеем. |
| Автор: math64 8.4.2013, 07:24 | ||
Примерно как написал volatile, но не функцию, а макрос - у контроллера обычно C без плюсов.
Если src_bit и dst_bit - константы, сдвиги выполнит компилятор. Можно добавить параметр bit_cnt для перемещения нескольких бит сразу. |
| Автор: bsa 8.4.2013, 11:06 | ||
gcc довольно хреново оптимизирует сдвиги. Например, для avr классический код получения старшего байта слова (x >> 8) будет выглядеть как восемь сдвигов всего числа... Что очень неоптимально. Чтобы это обойти я использовал объединение:
Более того, для работы с битами на AVR есть встроенная функция gcc: __builtin_avr_insert_bits(), которая позволяет тасовать биты. |
| Автор: xvr 8.4.2013, 13:17 |
А какой у вас МК и компилятор? К примеру gcc под ARM (с достаточным уровнем оптимизации) свернет код от volatile до прямого копирования битов (IMHO). Посмотрите ассемблерный выхлоп от компилятора - вас ждет сюрприз |
| Автор: Dem_max 8.4.2013, 15:24 |
| Я так подозреваю у тебя Cortex у него компилятор не должен ругаться на мою конструкцию |
| Автор: volatile 9.4.2013, 23:40 |
вы видимо не знаете что такое с/с++ компилятор. Этот код должен работать никак не медленнее вашего. особенно если учесть, что там фактически, вообще нет сдвигов. забыли добавить "по моим предположениям, ..." |