Easyelectronics.ru

Электроника для всех
Текущее время: 11 авг 2020, 03:43

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



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 20 ] 
Автор Сообщение
 Заголовок сообщения: Bit array с возможностью копировать (всем втыкать!)
СообщениеДобавлено: 02 май 2017, 14:29 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
в поиске готового Bit Array на С.
не хочу изобретать велосипед.

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

подобное обсуждается тут

но код который там приведён не работает даже с примитивным копированием 1 типа uint64_t из одной переменной в другую.

Код:
uint64_t test1 = 1;
uint64_t test2 = 0;
bitarray_copy(&test1, 0, 1, &test2, 0);

//test2==0 !!!!

_________________
unirail.org


Последний раз редактировалось cheblin 02 май 2017, 20:59, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 15:00 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 703
Доброго времени суток !

нужно скопировать n-бит из адреса src в адрес dst со смещением isrc и idst соответственно. Так как адресация у нас будет байтовая то индексы смещения бит могут принимать значения [0..7]
Код:
void bitCopy(uint8_t *src, uint8_t isrc, uint8_t *dst, uint8_t idst, uint16_t len) {

        uint8_t mask;
        while(len--){
                mask = (1 << idst);
                if (*src & (1 << isrc)) *dst |= mask; else *dst &= ~mask;
                if (++isrc == 8) {isrc = 0; src++;}
                if (++idst == 8) {idst = 0; dst++;}
        }
}

я думаю как то так должно работать


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 15:15 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
Код:
void bitCopy(uint8_t *src, uint8_t isrc, uint8_t *dst, uint8_t idst, uint16_t len) {

        uint8_t mask;
        while(len--){
                mask = (1 << idst);
                if (*src & (1 << isrc)) *dst |= mask; else *dst &= ~mask;
                if (++isrc == 8) {isrc = 0; src++;}
                if (++idst == 8) {idst = 0; dst++;}
        }
}


побитово! а ничё так... мне нра.! главное очень просто получается! Спасибо
можно слегка оптимизировать на случай если isrc==idst и 8 < len использовав memcpy

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

_________________
unirail.org


Последний раз редактировалось cheblin 02 май 2017, 15:25, всего редактировалось 3 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 15:19 
Старожил

Зарегистрирован: 07 авг 2014, 17:15
Сообщения: 383
Откуда: дальнее надмосковье
cheblin писал(а):
в поиске готового Bit Array на С.
не хочу изобретать велосипед.

Использовал с успехом эту библиотеку
Но там свой тип, оперировать на простых типах С (например uint64_t) не получится.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 15:30 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
arm999 писал(а):
cheblin писал(а):
в поиске готового Bit Array на С.
не хочу изобретать велосипед.

Использовал с успехом эту библиотеку
Но там свой тип, оперировать на простых типах С (например uint64_t) не получится.


спасибо за ответ, да, видел этот жуткий мрак...

код приведённый уважаемым void1509 позволяет в простой и понятной форме, выполнить все функции той библиотеки.

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 15:40 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 703
2cheblin Вы просили побитово - я привел универсальную функцию копирования побитно с произвольным смещением исходника и произвольным смещением приемника. Если у Вас большие массивы данных, то есть конечно смысл рассмотреть копирование по словам с оптимизацией под конкретный случай.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 15:53 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
я не просил побитово.
Но Вам в любом случае спасибо.
побитовый вариант - хорошее начало.

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 15:58 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 3446
Код:
while (len--){
  if (src[isrc >> 3] & (1<<(isrc & 0x07))) dst[idst >> 3] |= (1<<(idst & 0x07)); else dst[idst >> 3] &= ~(1<<(idst & 0x07));
  idst += 1;
  isrc += 1;
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 16:02 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 703
Да действительно, Вы не писали побитово. Но с произвольной битовой адресацией. Если бы хотяб приемник был выровнян по байтно, то можно было бы перейти к байтам или даже словам. А так при записи Вам сначала прийдется обнулить нужные биты, а потом записать. Это сильно усложнит алгоритм и не прибавит производительности. Но в некоторых частных случаях (к примеру idst == 0) можно оптимизироваться.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 16:07 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 703
2_pv Тогда уж так:
Код:
while (len--) if (src[isrc >> 3] & (1<<(isrc++ & 0x07))) dst[idst >> 3] |= (1<<(idst++ & 0x07)); else dst[idst >> 3] &= ~(1<<(idst++ & 0x07));

;))


Последний раз редактировалось void1509 02 май 2017, 16:09, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 16:07 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
void1509 писал(а):
...можно оптимизироваться.

сейчас засел над этим...

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 16:09 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
_pv писал(а):
Код:
while (len--){
  if (src[isrc >> 3] & (1<<(isrc & 0x07))) dst[idst >> 3] |= (1<<(idst & 0x07)); else dst[idst >> 3] &= ~(1<<(idst & 0x07));
  idst += 1;
  isrc += 1;
}


isrc и idst -принимают значения от 0 до 7.

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 16:13 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 703
Нет, в приведенной _pv оптимизацией тип у isrc и idst должен быть такой же как у len и индексация идет произвольная [0..len] бит


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 16:20 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
_pv писал(а):
Код:
while (len--){
  if (src[isrc >> 3] & (1<<(isrc & 0x07))) dst[idst >> 3] |= (1<<(idst & 0x07)); else dst[idst >> 3] &= ~(1<<(idst & 0x07));
  idst += 1;
  isrc += 1;
}


а тоже клёво. спасибо

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 20:57 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
вот что получается в итоге...

Код:
#define COPY_BIT() {dst[dst_bit++ >> 3] = src[src_bit >> 3] & 1 << (src_bit++ & 0x07) ? dst[dst_bit >> 3] | 1 << (dst_bit & 0x07) : dst[dst_bit >> 3] & ~(1 << (dst_bit & 0x07));len_bits--;}

void bitCopy(const uint8_t* src, uint8_t src_bit, uint16_t len_bits,  uint8_t* dst, uint8_t dst_bit)
{
   if (15 < len_bits &&  (src_bit & 0x07) == (dst_bit & 0x07) )
      if ((src_bit & 0x07) == 0 && (len_bits & 0x07) == 0)
      {
         memcpy(dst, src, len_bits / 8);
         return;
      }
      else
      {
         while (8 - src_bit & 0x07)
         COPY_BIT()

         memcpy(dst + dst_bit / 8, src + src_bit / 8, len_bits >> 3);
         dst_bit += len_bits & ~7;
         src_bit += len_bits & ~7;
         len_bits &= 0x07;
      }

   while (len_bits)
   COPY_BIT()
}


критика приветствуется !

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 21:06 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 703
По поводу COPY_BIT - я Вам привел код цикла в 1 строку 6 постов выше и лучше делать не матросом препроцессора, а инлайн функцией


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать
СообщениеДобавлено: 02 май 2017, 21:15 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
void1509 писал(а):
По поводу COPY_BIT - я Вам привел код цикла в 1 строку 6 постов выше и лучше делать не матросом препроцессора, а инлайн функцией


приглядитесь я все идеи (спасибо всем) , и Вашу тоже, использовал.
макрос тут вполне уместен, ибо он очень примитивный.
с инлайн функцией пришлось бы громоздить передачу 5 параметров. смотрелось бы коряво.

попробуйте сами. ещё раз спасибо за участие!

_________________
unirail.org


Последний раз редактировалось cheblin 02 май 2017, 21:19, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать (всем втыкать!)
СообщениеДобавлено: 02 май 2017, 21:18 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 703
Далее по коду
Код:
void bitCopy(const uint8_t* src, uint8_t src_bit, uint16_t len_bits,  uint8_t* dst, uint8_t dst_bit)
{
   if (15 < len_bits &&  (src_bit & 0x07) == (dst_bit & 0x07) )
      if ((src_bit & 0x07) == 0 && (len_bits & 0x07) == 0)
      // я бы сделал так if (!((src_bit | dst_bit | len_bits) & 7))
      {
         memcpy(dst, src, len_bits / 8);
         //memcpy(dst, src, len_bits >> 3);  операция сдвига в отличии от деления в 1 такт
         return;
      }
      else
      {
         while (8 - src_bit & 0x07) // 8 - src_bit - может быть переполнение если src_bit > 8
         COPY_BIT()

         memcpy(dst + dst_bit / 8, src + src_bit / 8, len_bits >> 3);
         dst_bit += len_bits & ~7;
         src_bit += len_bits & ~7;
         len_bits &= 0x07;
         // честно говоря, что вы хотите сделать этим блоком я не понял
      }


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать (всем втыкать!)
СообщениеДобавлено: 02 май 2017, 21:28 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
пояснения
Код:
........

else
      {
         while (8 - src_bit & 0x07) //начало копируем побитно, до выравнивания до начала байта
         COPY_BIT()

         memcpy(dst + (dst_bit >> 3), src + (src_bit >> 3), len_bits >> 3); //копируем то, что можно копировать побайтно

         dst_bit += len_bits & ~7; //ДОнаращиваем после memcpy
         src_bit += len_bits & ~7;

         len_bits &= 0x07; //возможно остался недокопированным хвост в несколько бит, кладём его в len_bits чтобы воспользоваться далее стандартным макросом
      }

   while (len_bits)
   COPY_BIT()

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Bit array с возможностью копировать (всем втыкать!)
СообщениеДобавлено: 02 май 2017, 21:37 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3469
Откуда: Китай, Пекин
Изображение
Код:
#define COPY_BIT() {dst[dst_bit++ >> 3] = src[src_bit >> 3] & 1 << (src_bit++ & 0x07) ? dst[dst_bit >> 3] | 1 << (dst_bit & 0x07) : dst[dst_bit >> 3] & ~(1 << (dst_bit & 0x07));len_bits--;}

void bitCopy(const uint8_t* src, uint8_t src_bit, uint16_t len_bits,  uint8_t* dst, uint8_t dst_bit)
{
   if (15 < len_bits &&  (src_bit & 0x07) == (dst_bit & 0x07) )
      if ((src_bit & 0x07) == 0 && (len_bits & 0x07) == 0)
      {
         memcpy(dst, src, len_bits / 8);
         return;
      }
      else
      {
         while (8 - src_bit & 0x07) //начало копируем побитно, до выравнивания до начала байта
         COPY_BIT()

         memcpy(dst + (dst_bit >> 3), src + (src_bit >> 3), len_bits >> 3); //копируем то, что можно копировать побайтно

         dst_bit += len_bits & ~7;//ДОнаращиваем после memcpy
         src_bit += len_bits & ~7;
         //возможно остался недокопированным хвост в несколько бит, кладём его в len_bits и пользуемся макросом побитного копирования
         len_bits &= 0x07;
      }

   while (len_bits)
   COPY_BIT()
}

_________________
unirail.org


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 20 ] 


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


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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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

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