Easyelectronics.ru • Просмотр темы - развернуть битовый массив

Easyelectronics.ru

Электроника для всех
Текущее время: 18 авг 2018, 07:45

Часовой пояс: UTC + 5 часов



    • JLCPCB - Прототипы 10 PCBs всего за 2$ (100*100mm, 2-layer)
    • Как мы делаем платы, смотрите на YouTube
    • Крупнейшая китайская фабрика прототипов. 300000+ заказчиков и 10000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин комплектующих.

Начать новую тему Ответить на тему  [ Сообщений: 62 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: развернуть битовый массив
СообщениеДобавлено: 19 фев 2018, 18:04 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
ув. форумчане, подскажите вариант решения, необходимо развернуть массив 144 бит, не инвертировать, а именно развернуть, т.е. было к примеру 0B01001101101... а стало 0B1011011001...?


Последний раз редактировалось Volldemar 20 фев 2018, 14:43, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив
СообщениеДобавлено: 19 фев 2018, 18:15 
Старожил
Аватара пользователя

Зарегистрирован: 14 апр 2014, 11:06
Сообщения: 1283
Откуда: Курск
Типа такого, без привязки к языку программирования:
Код:
for (i=0; i<144;i++) {
print(array[144-i])
}

или
Код:
for (i=0; i<144;i++) {
array2[i]=array1[144-i]
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 19 фев 2018, 18:21 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
Cthulhu писал(а):
Типа такого, без привязки к языку программирования:
Код:
for (i=0; i<144;i++) {
print(array[144-i])
}

или
Код:
for (i=0; i<144;i++) {
array2[i]=array1[144-i]
}

Ок, спс!!!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив
СообщениеДобавлено: 19 фев 2018, 18:24 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2114
__REV(word) возвратит реверсированное 4-байтное слово. __REV16 - для 2-хбайтного полуслова. Это обертки ассемблерных инструкций реверса бит.
Cthulhu, не байт, а бит. 144 бита, это 18 байт


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив
СообщениеДобавлено: 19 фев 2018, 18:35 
Старожил
Аватара пользователя

Зарегистрирован: 14 апр 2014, 11:06
Сообщения: 1283
Откуда: Курск
BusMaster писал(а):
Cthulhu, не байт, а бит. 144 бита, это 18 байт

Так массив же )))
Про 18 байт у ТС ни слова. Как массив задан ни слова. И т.д. )))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив
СообщениеДобавлено: 19 фев 2018, 18:55 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
Cthulhu писал(а):
BusMaster писал(а):
Cthulhu, не байт, а бит. 144 бита, это 18 байт

Так массив же )))
Про 18 байт у ТС ни слова. Как массив задан ни слова. И т.д. )))

Массив байтовый, но информация в массиве битовая последовательность, перед выдачей наружу, необходимо "развернуть" весь массив битов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 19 фев 2018, 19:06 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2114
Ну строго говоря, массивы считаются в байтах, поскольку минимальный размер хранимой инфы - 1 байт.
Код:
   uint8_t array[18] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
   uint8_t array2[18] = {0};
   for(int i=0; i<18; i++)
   {
      array2[i] = (__RBIT(array[17-i])>>24);; // сдвиг на 24 бита - это если элемент массива - однобайтный
   }


Вложения:
Без-имени-1.jpg
Без-имени-1.jpg [ 67.05 Кб | Просмотров: 1295 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 19 фев 2018, 19:26 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
BusMaster писал(а):
Ну строго говоря, массивы считаются в байтах, поскольку минимальный размер хранимой инфы - 1 байт.
Код:
   uint8_t array[18] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
   uint8_t array2[18] = {0};
   for(int i=0; i<18; i++)
   {
      array2[i] = (__RBIT(array[17-i])>>24);; // сдвиг на 24 бита - это если элемент массива - однобайтный
   }

судя по картинке, то есть несоответствие, в чёрном квадратике из array не соответствует красному из array2.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 19 фев 2018, 19:53 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2114
Я думал, вы поймете без слов, как читать картинку. Черные и красные квардратики - на цвет не надо акцентироваться, это информация чисто отладчика. А нас интересует лишь границы массива, обведенные фиолетовой рамкой. Начиная от верхнего красного квадратика array2 отсчитыываем 18 байт по 8 бит (=144 бита) - это второй, реверсированный массив, его границы обведены фиолетовой рамкой.
Ниже, начиная от красного квадратика - исходный массив array, так же 18 байт.
Все биты последовательно в массиве array2 представляют собой полное реверсирование порядка битов из массива array. То есть, в красном квадратике array2 (первый его байт) содержится реверсированный последний байт исходного массива array. Второй байт array2 - это реверсированный предпоследний байт исходного array.
00010001
10001000
Вот так лучш видно?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 19 фев 2018, 20:01 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
ок, спс за разъяснение!!!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 00:55 
Старожил
Аватара пользователя

Зарегистрирован: 18 фев 2014, 11:27
Сообщения: 211
перевернуть байт
Код:
in - входной байт
   unsigned char out;
in = ((in & 0x0F) << 4) | ((in & 0xF0) >> 4);
   in = ((in & 0x33) << 2) | ((in & 0xCC) >> 2);
   out = ((in & 0x55) << 1) | ((in & 0xAA) >> 1);
out - перевернутый in


Последний раз редактировалось mishany984 22 фев 2018, 10:32, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 01:28 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2483
Откуда: Санкт-Петербург
Интересно, кстати, оптимизирует ли компилятор это всё в одну инструкцию (для процов, на которых есть инструкция разворота байта)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 02:24 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 608
mishany984 писал(а):
перевернуть байт
Код:
in - входной байт
   unsigned char tmp, out;
   tmp = ((in & 0x33) << 2) | ((in & 0xCC) >> 2);
   out = ((tmp & 0x55) << 1) | ((tmp & 0xAA) >> 1);
out - перевернутый in

Это не для байта, а для тетрад.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 04:53 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 456
BusMaster писал(а):
Ну строго говоря, массивы считаются в байтах, поскольку минимальный размер хранимой инфы - 1 байт.
Код:
   uint8_t array[18] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
   uint8_t array2[18] = {0};
   for(int i=0; i<18; i++)
   {
      array2[i] = (__RBIT(array[17-i])>>24);; // сдвиг на 24 бита - это если элемент массива - однобайтный
   }


А почему в байтах ? rbit обрабатывает слово и судя по ">>24" уважаемому BusMaster это известно. Массив в 5 слов обрабатывается быстрее чем 18 слов. А читать его потом можно и побайтно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 07:42 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2114
Для наглядности объяснения


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 13:58 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
добавлю подробностей:
есть структура:
Код:
typedef struct __attribute__((packed))
{
   uint8_t hfd;
   unsigned i      : 1;
   unsigned n      : 4;
   unsigned v      : 1;
   unsigned z      : 1;
   unsigned c1      : 6;
   unsigned c2   : 1;
   unsigned d      : 11;
   unsigned v1      : 7;
   int16_t   v2;
   unsigned k      : 9;
   unsigned s           : 6;
   unsigned l1      : 7;
   unsigned l2      : 6;
   unsigned l3      : 11;
   unsigned p1            : 1;
   unsigned l4      : 8;
   unsigned l5      : 6;
   unsigned l6      : 11;
   unsigned p2           : 1;
   unsigned a      : 1;
   unsigned r      : 5;
   uint8_t crc8;
   uint8_t efd;
} TXpsp_t;
которая укладывается в массив из 18 байт, так вот задача перевернуть массив так, что бы не было "разрывов" информации, так как поля структуры не кратны байту, т.е. произвести побитный разворот 144 битов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 16:13 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 2929
Код:
TXpsp_t s1, s2;
uint32_t * p1 = &s1;
uint32_t * p2 = &s2;
p2[0] = (__RBIT(p1[4]) >> 16) | (__RBIT(p1[3])<<16);
p2[1] = (__RBIT(p1[3]) >> 16) | (__RBIT(p1[2])<<16);
p2[2] = (__RBIT(p1[2]) >> 16) | (__RBIT(p1[1])<<16);
p2[3] = (__RBIT(p1[1]) >> 16) | (__RBIT(p1[0])<<16);
*(uint16_t*)(&p2[4]) = __RBIT(p1[0])>>16;


Последний раз редактировалось _pv 20 фев 2018, 17:33, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 16:32 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 456
Ну и я тогда добавлю подробностей
Код:
typedef struct  __attribute__((packed))
{
   uint8_t hfd;
   unsigned i      : 1;
   unsigned n      : 4;
   unsigned v      : 1;
   unsigned z      : 1;
   unsigned c1      : 6;
   unsigned c2   : 1;
   unsigned d      : 11;
   unsigned v1      : 7;
   int16_t   v2;
   unsigned k      : 9;
   unsigned s           : 6;
   unsigned l1      : 7;
   unsigned l2      : 6;
   unsigned l3      : 11;
   unsigned p1            : 1;
   unsigned l4      : 8;
   unsigned l5      : 6;
   unsigned l6      : 11;
   unsigned p2           : 1;
   unsigned a      : 1;
   unsigned r      : 5;
   uint8_t crc8;
   uint8_t efd;
} TXpsp_t;

uint32_t bufsrc[5];
uint32_t bufdst[5];
uint8_t *sh,cnt = 5;

        TXpsp_t *save = (TXpsp_t*)bufsrc;
        // заполняем
        save->i = 1;
        save->n = 2;
        // и так далее
        while(cnt--) dst[4-cnt] = __RBIT(src[cnt]);  переварачиваем
        sh = (uint8_t*) dst; sh += 2;
        send(sh, 18);

я вижу как то так.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 16:44 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 456
_pv писал(а):
Код:
TXpsp_t s;
uint32_t * p = &s;   /* так делать нельзя, так как TXpsp_t объявлен как packed, а значит выравнивание по 4 байта отменено. То есть адрес может быть не кратный 4, значит к нему нельзя будет обращаться как к слову. */
p[0] = __RBIT(p[0]);
p[1] = __RBIT(p[1]);
p[2] = __RBIT(p[2]);
p[3] = __RBIT(p[3]);
*(uint16_t*)(&p[4]) = __RBIT(p[4])>>16;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 16:53 
Старожил

Зарегистрирован: 18 июл 2016, 21:17
Сообщения: 746
Код:
for(i=0;i<144;i++)
  {
   if(GetBit(i))SetBit(144-i);
   else ClrBit(144-i);
  }

Как то так :)


Последний раз редактировалось bw429 20 фев 2018, 17:20, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 17:15 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 2929
void1509 писал(а):
так делать нельзя, так как TXpsp_t объявлен как packed, а значит выравнивание по 4 байта отменено. То есть адрес может быть не кратный 4, значит к нему нельзя будет обращаться как к слову.

отменено выравнивание внутри структуры.
атрибуты packed и aligned это не одно и то же.
можно указать ((packed, aligned(4))), но оно и так 4 должно быть по умолчанию, не?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 20:04 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 456
_pv писал(а):
void1509 писал(а):
так делать нельзя, так как TXpsp_t объявлен как packed, а значит выравнивание по 4 байта отменено. То есть адрес может быть не кратный 4, значит к нему нельзя будет обращаться как к слову.

отменено выравнивание внутри структуры.
атрибуты packed и aligned это не одно и то же.
можно указать ((packed, aligned(4))), но оно и так 4 должно быть по умолчанию, не?


можно, тогда у вас упаковка будет происходить элементами кратным 4-м байтам. По умолчанию packed упаковывает по 1-му байту (как минимальный элемент).
https://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Type-Attributes.html
А если размещение идет по 1 байту, то предидущий элемент может быть размером не кратным 4. Соответственно ваша структура сместится. То есть uint8_t aa; my_pack_struct bb; будет адр:0 аа и адр:1 bb. А если uint8_t aa; my_unpack_struct bb; будет адр:0 аа и адр:4 bb.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 20:33 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 2929
packed отвечает за упаковку элементов внутри структуры, а aligned - за выравнивание всей структуры целиком (без относительно того упакована она или нет), а не отдельных элементов в ней. Это два разных атрибута.

struct S { short f[3]; } __attribute__ ((aligned (8))); по прежнему будет размером 6 байт, но сама структура (первый элемент) начинаться будет с адресов кратным 8.

соответственно вышеописанная упакованная структура скорее всего будет выровнена по 4 байтам, тупо из-за наличия в ней intов, хоть с упаковкой, хоть без.

Цитата:
alignment of any given struct or union type is required by the ISO C standard to be at least a perfect multiple of the lowest common multiple of the alignments of all of the members of the struct


то что у них указан размер меньше и они упакованы на размещение думаю не повлияет, но лучше конечно указать прямо ((packed, aligned(4)))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 20:48 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2114
Что вы спорите?? Посмотрите в отладчике браузер памяти и реальное расположение переменных по байтам. Подобно той картинке, которую я выше приводил. Все спорные моменты сразу встанут на свои места.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 21:11 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 456
Вы знаете не поленился и накидал простенько
Код:
typedef struct __attribute__((__packed__)) {
   uint16_t    a;
   uint8_t       b;
} MyPack_t;

volatile uint8_t q1;
volatile MyPack_t q2;
uint16_t cnt, bit, nbt;


а теперь внимание .map файл
Цитата:
*(.data_end .data_end.*)
0x000000002000001c . = ALIGN (0x4)
// бла-бла-бла .....................

COMMON 0x0000000020000024 0xb ./src/main.o
0x0000000020000024 nbt
0x0000000020000026 q2
0x000000002000002a bit
0x000000002000002c cnt
0x000000002000002e q1

Прошу обратить внимание nbt - 2-ва байта, за ним идет структура и несмотря на то что ALIGN 4, начинается структура с адреса кратного 2-ум.
То есть сразу по окончанию предидущей переменной.
А вот то же самое только без packed:
Цитата:
COMMON 0x0000000020000024 0xd ./src/main.o
0x0000000020000024 nbt
0x0000000020000028 q2
0x000000002000002c bit
0x000000002000002e cnt
0x0000000020000030 q1

Обратите внимание на адрес q2
Итого подитожу - в первом случае обращение к структуре как к указателю uint32_t *st = &q2; вызывало бы ошибку так как адрес q2 был не кратен 4.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 62 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB