Easyelectronics.ru

Электроника для всех
Текущее время: 13 дек 2018, 02:51

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




Начать новую тему Ответить на тему  [ Сообщений: 5 ] 
Автор Сообщение
 Заголовок сообщения: Вычитывание битовых полей из байтового массива
СообщениеДобавлено: 26 янв 2018, 12:51 
Старожил
Аватара пользователя

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

Код:
#ifdef   UINT64_MAX
typedef uint64_t UMAX;
#else
typedef  uint32_t UMAX;
#endif

const uint8_t Ol[] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
const uint8_t lO[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };

UMAX get_bits(uint8_t* src, uint32_t bit, uint16_t bits)
{
    src += bit » 3;
    bit &= 7;
    if(sizeof(UMAX) < bits » 3) bits = sizeof(UMAX) « 3;
    else if(bit + bits < 9) return *src » bit & Ol[bits];
    UMAX dst = 0;
    memcpy(&dst, src, bit + bits » 3);
    dst »= bit;
    src += bit + bits » 3;
    bit = bit + bits & 7;
    if(0 < bit) dst |= (UMAX)(*src & Ol[bit]) « bits - bit;
    return dst;
}


работоспособность проверенна на многочисленных тестах...
был бы рад услышать как и что ещё можно улучшить.


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

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 3059
cheblin писал(а):
Кусок ...
Код:
    memcpy(&dst, src, bit + bits » 3);

работоспособность проверенна на многочисленных тестах...

работоспособность данного, так сказать, куска сильно зависит от того в какую сторону стек растёт, (а он на всех платформах растёт в одну и ту же сторону).
вам просто повезло :)


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

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 1622
Откуда: Китай, Пекин
_pv писал(а):
cheblin писал(а):
Кусок ...
Код:
    memcpy(&dst, src, bit + bits » 3);

работоспособность проверенна на многочисленных тестах...

работоспособность данного, так сказать, куска сильно зависит от того в какую сторону стек растёт, (а он на всех платформах растёт в одну и ту же сторону).
вам просто повезло :)


я не понял. если не сложно разверните свое замечание.

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

как интерпретировать полученое? в некоторых случаях это готовое значение, в других, для получения реального значения потребуется реверс.


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

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 3059
cheblin писал(а):
я не понял. если не сложно разверните свое замечание.

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

и уверены, что это будет работать сильно быстрее чем тупо побитовое копирование:
Код:
void bitcpy(uint8_t * dst, size_t dst_offset, uint8_t * src, size_t src_offset, size_t bit_count){
  while (bit_count--)
    if src[src_offset>>3] & (1<<(src_offset++&7)) dst[dst_offset>>3] |= (1<<(dst_offset++&7)) else dst[dst_offset>>3] &= ~(1<<(dst_offset++&7));
}


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

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

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

и уверены, что это будет работать сильно быстрее чем тупо побитовое копирование:
Код:
void bitcpy(uint8_t * dst, size_t dst_offset, uint8_t * src, size_t src_offset, size_t bit_count){
  while (bit_count--)
    if src[src_offset>>3] & (1<<(src_offset++&7)) dst[dst_offset>>3] |= (1<<(dst_offset++&7)) else dst[dst_offset>>3] &= ~(1<<(dst_offset++&7));
}

а сами-то как думаете?
только в самом простейшем случае будет одинакого.
а в случае когда в моём варианте отработает только memcpy - многократно.

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

в любом случае, Вам спасибо, за критический взгляд.


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

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


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

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


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

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

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