Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> биты в байты и обратно %) 
V
    Опции темы
boostcoder
Дата 26.5.2012, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



всем привет!

снова мне повстречалась задача с битами smile 
прошу помощи.

имеем класс, описывающий битовое множество(QBitArray)
нужно это дело поместить в массив байт, и обратно.

я не очень-то понимаю как мне итерироваться по битам каждого байта массива.

спасибо.

PM WWW   Вверх
boostcoder
Дата 26.5.2012, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



в общем, нагуглил два решения:
http://stackoverflow.com/questions/8776261...y-to-qbytearray
http://stackoverflow.com/questions/5251403...on-of-stdbitset

и сразу понял как реализовать задачу smile (еще бы)))

но решение для QBitArray что-то мне кажется дико оверхедным...
у кого-то есть предложения по оптимизации?
PM WWW   Вверх
volatile
Дата 27.5.2012, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(boostcoder @  26.5.2012,  23:48 Найти цитируемый пост)
но решение для QBitArray что-то мне кажется дико оверхедным...

Если бы знать внутреннее устройство QBitArray, то вероятно было бы оптимальное решение. (возможно даже memcpy)
Но, увы мы так делать не имеем право, так что кардинально там несоптимизируешь.
Так по мелочи, конечно можно, но это не даст заметного ускорения.

А вот исправить баг, в первом линке, не помешает
Цитата

  bytes.resize(bits.count()/8);


Если кол-во битов не кратно 8, то программка сильно обломится.
нужно как-то так:
Цитата

  bytes.resize((bits.count() + 7)/8);



PM MAIL   Вверх
boostcoder
Дата 27.5.2012, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(volatile @  27.5.2012,  00:15 Найти цитируемый пост)
А вот исправить баг, в первом линке, не помешает

о, спасибо  smile 

ладно, вопрос закрываю.

PM WWW   Вверх
volatile
Дата 27.5.2012, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Кстати там ниже, это испривили, (только что посмотрел)
Цитата

bytes.resize(bits.count()/8+1);

Но все равно, мой вариант, более точный:
Цитата(volatile @  27.5.2012,  00:15 Найти цитируемый пост)
bytes.resize((bits.count() + 7)/8);


PM MAIL   Вверх
mes
Дата 27.5.2012, 00:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  26.5.2012,  22:48 Найти цитируемый пост)
у кого-то есть предложения по оптимизации? 

написать Qt, зато что лишила доступа к внутренней прослойке smile ведь могла б  возвращать data (), как ByteArray...



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 27.5.2012, 01:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



mes, а ведь в стандартной реализации этого тоже нет: http://en.cppreference.com/w/cpp/utility/bitset

Добавлено через 2 минуты и 50 секунд
и в boost.dynamic_bitset этого тоже нет, почему-то.
PM WWW   Вверх
mes
Дата 27.5.2012, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.5.2012,  00:04 Найти цитируемый пост)
этого тоже нет: http://en.cppreference.com/w/cpp/utility/bitset

ага, там ограничились u(l)long'ом... сам не так давно возмущался их поведением smile

Добавлено через 3 минуты и 20 секунд
Цитата(boostcoder @  27.5.2012,  00:04 Найти цитируемый пост)
и в boost.dynamic_bitset этого тоже нет, почему-то. 

там хоть to_block_range есть smile


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 27.5.2012, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  27.5.2012,  09:02 Найти цитируемый пост)
там хоть to_block_range есть

да, точно smile

Цитата(mes @  27.5.2012,  09:02 Найти цитируемый пост)
там ограничились u(l)long

Вы про то, что внутреннее хранилище состоит из массива long`ов?
PM WWW   Вверх
mes
Дата 27.5.2012, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.5.2012,  11:19 Найти цитируемый пост)
Вы про то, что внутреннее хранилище состоит из массива long`ов? 

про возвращение набора битов как u(l)long, размера которого увы не всегда хватает..а о массиве  они почему то не подумали..


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 27.5.2012, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



ааа, ну да.
но раз уж все известные мне реализации поступают так же, возможно есть на то причина?
PM WWW   Вверх
mes
Дата 27.5.2012, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.5.2012,  12:00 Найти цитируемый пост)
но раз уж все известные мне реализации поступают так же, возможно есть на то причина? 

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



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 27.5.2012, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



ясно)
PM WWW   Вверх
borisbn
Дата 27.5.2012, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



у всех этих "стандартных" битсетов (что std, что boost, что Qt) есть один недостаток: они складывают биты в байте начиная с младшего.
Например, последовательность 10101100 будет равна 0x35, а многие библиотеки (да почти все) требуют, чтобы биты складывались, начиная со старшего бита. Т.о. приведённая последовательность должна быть равна 0xAC, а не 0x35.
Так что советую реализовать свой битсет (можно без блекджека))). Тем более, что это - совсем нетрудно

Это сообщение отредактировал(а) borisbn - 27.5.2012, 13:58


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
hawk3500
Дата 29.5.2012, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 246
Регистрация: 6.2.2009

Репутация: нет
Всего: 2



Занимаюсь ЦОС. На ПК более быстрого и прозрачного решения чем ниже описанное не нашёл.
Да не экономично по отношению к памяти , зато быстро и прозрачно.

Код

//Класс для распаковки битов
bool BIN_GO2[256][8];
int GetBitFromBuff(char buff,int n)
{
    return (buff&(1<<((n%8))))!=0;
}
clsBlock::clsBlock(void ) 
{
    // Подготовка к работе, инициализация переменных
char V;
for(int i=0;i<256;i++)
{
    V=char(i);
    BIN_GO2[i][0]=bool(GetBitFromBuff(V,0));
    BIN_GO2[i][1]=bool(GetBitFromBuff(V,1));
    BIN_GO2[i][2]=bool(GetBitFromBuff(V,2));
    BIN_GO2[i][3]=bool(GetBitFromBuff(V,3));
    BIN_GO2[i][4]=bool(GetBitFromBuff(V,4));
    BIN_GO2[i][5]=bool(GetBitFromBuff(V,5));
    BIN_GO2[i][6]=bool(GetBitFromBuff(V,6));
    BIN_GO2[i][7]=bool(GetBitFromBuff(V,7));
}
}

void clsBlock::CharToBit(unsigned char *IN_MASS,bool *OUT_MASS,int In_Mass_Lenght)
{
    int next_position=0;
    int current_byte=0;
    int tmp=0;
    int byte_size=8*sizeof(bool);
    memset(OUT_MASS,0,In_Mass_Lenght*sizeof(bool));
    while(current_byte<In_Mass_Lenght)
    {
        tmp=int(IN_MASS[current_byte]);
        memcpy(&OUT_MASS[next_position],&BIN_GO2[tmp][0],byte_size);
        next_position+=8;
        current_byte++;
    }
return;
}







//класс для упаковки

bool BIN_GO2[256][8];
char PARSE[2][2][2][2][2][2][2][2];
int GetBitFromBuff(char buff,int n)
{
    return (buff&(1<<((n%8))))!=0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Конструктор класса
clsBlock::clsBlock(void )
    // Подготовка к работе, инициализация переменных

char V;
for(int i=0;i<256;i++)
{
    V=char(i);
    BIN_GO2[i][0]=bool(GetBitFromBuff(V,0));
    BIN_GO2[i][1]=bool(GetBitFromBuff(V,1));
    BIN_GO2[i][2]=bool(GetBitFromBuff(V,2));
    BIN_GO2[i][3]=bool(GetBitFromBuff(V,3));
    BIN_GO2[i][4]=bool(GetBitFromBuff(V,4));
    BIN_GO2[i][5]=bool(GetBitFromBuff(V,5));
    BIN_GO2[i][6]=bool(GetBitFromBuff(V,6));
    BIN_GO2[i][7]=bool(GetBitFromBuff(V,7));
}

for(int j=0;j<256;j++)
{
    PARSE[!!BIN_GO2[j][0]][!!BIN_GO2[j][1]][!!BIN_GO2[j][2]][!!BIN_GO2[j][3]][!!BIN_GO2[j][4]][!!BIN_GO2[j][5]][!!BIN_GO2[j][6]][!!BIN_GO2[j][7]]=char(j);
}

}


void clsBlock::BitToChar(bool *IN_MASS,char *OUT_MASS,int In_Mass_Lenght)
{
    int OUT_POS=0;
    int loacl_lenght=In_Mass_Lenght/8;
    for(int i=0;i<loacl_lenght;i++)
    {
        OUT_MASS[i]=PARSE[!!IN_MASS[OUT_POS]][!!IN_MASS[OUT_POS+1]][!!IN_MASS[OUT_POS+2]][!!IN_MASS[OUT_POS+3]][!!IN_MASS[OUT_POS+4]][!!IN_MASS[OUT_POS+5]][!!IN_MASS[OUT_POS+6]][!!IN_MASS[OUT_POS+7]];
        OUT_POS+=8;
    }
return;    
}





Это сообщение отредактировал(а) hawk3500 - 29.5.2012, 16:54
--------------------
воин dzen'a
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0632 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.