Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / битовые поля в структурах c++ / 11 сообщений из 11, страница 1 из 1
14.09.2016, 17:11
    #39309197
nop
nop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
Добрый всем день.
Столкнулся с такой проблемой. У меня есть двухбайтовая переменная, которую надо разделить на 2 переменные размером 5 бит и 11 бит. Для этой цели я создал простенькую структуру:
Код: plaintext
1.
2.
3.
4.
5.
6.
#pragma pack(push,1)
struct Struct {
byte value1 : 5;
short value2 : 11;
}
#pragma pack(pop)



Проверяю:
Код: plaintext
1.
2.
char a[] = "\x08\x03";
Struct *s = (Struct *)a;


В s->value1 должна быть единица, потому что в бинарном виде мы имеем: 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1
Где жирным - те самые 5 бит. Но в s->value1 лежит цифра 8, что соответствует 0 0 0 0 1 0 0 0, то есть почему-то в value1 записывается целый байт вместо 5-ти бит.
Собственно, вопрос. Почему? Я предполагаю, что между value1 и value2 ещё лежат 3 неиспользованных бита (для выравнивания, т.к. структура весит 3 байта вместо 2-ух). Если я прав, то как можно эти три бита объединить с value2? То есть чтобы вся структура имела реальный размер в памяти 2 байта.
...
Рейтинг: 0 / 0
14.09.2016, 17:18
    #39309202
nop
nop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
делать что-то типа
Код: plaintext
1.
2.
3.
4.
5.
struct Struct {
byte value1 : 5;
byte value21 : 3;
byte value22 : 8;
}


не красиво :/ есть ещё варианты?
...
Рейтинг: 0 / 0
14.09.2016, 17:19
    #39309203
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
nop,

Порядок байт
...
Рейтинг: 0 / 0
14.09.2016, 17:20
    #39309204
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
http://en.cppreference.com/w/cpp/language/bit_field
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
15.09.2016, 02:28
    #39309379
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
nop, да не мучайтесь вы с этими bitfield-ами, они по-разному реализованы в разных компиляторах, плюс заморочки с little-endian/big-endian (хотя big-endian архитектуры видимо почти вымерли). В C++ есть inline функции-члены, что делает C-шные bitfield-ы практически ненужными:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
#include <assert.h>

struct packed_values_t {
  unsigned short bits;
  int value_1() const {return bits & 0x1f;}
  int value_2() const {return bits >> 5;}
};
static_assert(sizeof(packed_values_t) == 2, "");

inline packed_values_t pack_values(int value_1, int value_2) {
  assert((0 <= value_1) && (value_1 <= 31)); // value_1 должно влезать в 5 битов
  assert((0 <= value_2) && (value_2 <= 2047)); // value_2 должно влезать в 11 битов
  return {value_1 | (value_2 << 5)};
}

int main() {
  packed_values_t pv = pack_values(11, 17);
  assert(pv.value_1() == 11);
  assert(pv.value_2() == 17);
  return 0;
}
...
Рейтинг: 0 / 0
15.09.2016, 08:19
    #39309416
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
Пётр Седов,

С ними понятнее и чище код, чем собирать побитово какой нибудь IP64
...
Рейтинг: 0 / 0
15.09.2016, 09:02
    #39309438
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
nopДобрый всем день.
Столкнулся с такой проблемой. У меня есть двухбайтовая переменная, которую надо разделить на 2 переменные размером 5 бит и 11 бит. Для этой цели я создал простенькую структуру:
Код: plaintext
1.
2.
3.
4.
5.
6.
#pragma pack(push,1)
struct Struct {
byte value1 : 5;
short value2 : 11;
}
#pragma pack(pop)



Проверяю:
Код: plaintext
1.
2.
char a[] = "\x08\x03";
Struct *s = (Struct *)a;


В s->value1 должна быть единица, потому что в бинарном виде мы имеем: 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1
Где жирным - те самые 5 бит. Но в s->value1 лежит цифра 8, что соответствует 0 0 0 0 1 0 0 0, то есть почему-то в value1 записывается целый байт вместо 5-ти бит.
Собственно, вопрос. Почему? Я предполагаю, что между value1 и value2 ещё лежат 3 неиспользованных бита (для выравнивания, т.к. структура весит 3 байта вместо 2-ух). Если я прав, то как можно эти три бита объединить с value2? То есть чтобы вся структура имела реальный размер в памяти 2 байта.
Всё не так. "\x08\x03" в бинарном виде - 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0. Первым идет младший байт. (Хотя это зависит от процессора, но на x86 вот так). Битовые поля компилятор тоже выделяет начиная с младших битов (но это может зависеть от компилятора). Так что value1 у вас не старшие, а младшие 5 битов. Действительно 8.
...
Рейтинг: 0 / 0
15.09.2016, 17:32
    #39309826
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
BarloneВсё не так. "\x08\x03" в бинарном виде - 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0. Первым идет младший байт. (Хотя это зависит от процессора, но на x86 вот так). Битовые поля компилятор тоже выделяет начиная с младших битов (но это может зависеть от компилятора). Так что value1 у вас не старшие, а младшие 5 битов. Действительно 8.Ты путаешь целое и строку.
"\x08\x03" и 0x0803 это разные вещи.
...
Рейтинг: 0 / 0
15.09.2016, 20:12
    #39309889
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
White OwlТы путаешь целое и строку.
"\x08\x03" и 0x0803 это разные вещи.
Наоборот, он как раз сказал, что "\x08\x03" это 0x0308 ))
...
Рейтинг: 0 / 0
16.09.2016, 06:35
    #39309972
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
White OwlBarloneВсё не так. "\x08\x03" в бинарном виде - 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0. Первым идет младший байт. (Хотя это зависит от процессора, но на x86 вот так). Битовые поля компилятор тоже выделяет начиная с младших битов (но это может зависеть от компилятора). Так что value1 у вас не старшие, а младшие 5 битов. Действительно 8.Ты путаешь целое и строку.
"\x08\x03" и 0x0803 это разные вещи.Это не я путаю, это автор пытается интерпретировать строку как целое число.
...
Рейтинг: 0 / 0
18.09.2016, 21:38
    #39311069
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
битовые поля в структурах c++
Siemargl, ещё одно преимущество bitfield-ов -- их легко в отладчике смотреть.

nop, если очень хочется именно bitfield-ы, можно так попробовать:
Код: plaintext
1.
2.
3.
4.
5.
struct packed_values_t {
  unsigned short value_1:5;
  unsigned short value_2:11;
};
static_assert(sizeof(packed_values_t) == 2, "");
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / битовые поля в структурах c++ / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]