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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> выделение данных из переменной 
:(
    Опции темы
kuvshinka
Дата 7.6.2011, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



допустим у меня есть переменная типа short:
Код

short parametr;

1.а как из этой 16-ти разрядной(битной) переменной выделить (записать в отдельную переменную) допустим 5,6 (или только допустим 7-ой, или крайние - 15-ый и 0-ой) разряды (биты)?
2. и наоборот - в, например, 12-ый бит переменной parametr записать "1"?
в Си (С++) читала про операторы сдвига >>, << и &, но до конца не поняла как ими пользоваться и прошу объяснить (дать маленький комментарий к ответу) конкретно на данном примере...или может в кути есть какие-то свои методы под это дело???   
PM MAIL   Вверх
borisbn
Дата 8.6.2011, 05:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Код

template< typename T >
unsigned char getBit( T x, unsigned int bitNum ) {
  assert( bitNum < sizeof( x ) * 8 );
  return (x >> bitNum) & 0x1;
}

template< typename T >
void setBit( T & x, unsigned int bitNum, unsigned char bitValue ) {
  assert( bitNum < sizeof( x ) * 8 );
  x &= ~(1 << bitNum);
  x |=  ( bitValue & 0x1 ) << bitNum;
}


Это сообщение отредактировал(а) borisbn - 8.6.2011, 09:56


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 31.3.2011
Где: Россия, Москва

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



Еще в си есть union и битсеты - можно ими.
PM MAIL WWW   Вверх
borisbn
Дата 8.6.2011, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(afiskon @  8.6.2011,  06:42 Найти цитируемый пост)
Еще в си есть union и битсеты - можно ими.

ага, забыл.
Код

union ShortBitSet {
  struct {
      unsigned short bit0 : 1;
      unsigned short bit1 : 1;
      unsigned short bit2 : 1;
      unsigned short bit3 : 1;
      unsigned short bit4 : 1;
      unsigned short bit56 : 2;
      unsigned short bit7 : 1;
      unsigned short bit8 : 1;
      unsigned short bit9 : 1;
      unsigned short bit10 : 1;
      unsigned short bit11 : 1;
      unsigned short bit12 : 1;
      unsigned short bit13 : 1;
      unsigned short bit14 : 1;
      unsigned short bit15 : 1;
  };
  unsigned short asShort;
};


Цитата(kuvshinka @  7.6.2011,  20:28 Найти цитируемый пост)

1.а как из этой 16-ти разрядной(битной) переменной выделить (записать в отдельную переменную) допустим 5,6 (или только допустим 7-ой, или крайние - 15-ый и 0-ой) разряды (биты)?

Код

ShortBitSet x;
x.asShort = ...;
unsigned short bit56 = x.bit56;
unsigned short bit7 = x.bit7;
unsigned short bit15 = x.bit15;
unsigned short bit0 = x.bit0;

или из предыдущего примера
Код

unsigned short bit15 = getBit( x, 15 );
unsigned short bit56 = getBit( x, 5 ) | ( getBit( x, 6 ) << 1 ); 
// или
unsigned short bit56 = (x >> 5 ) & 0x3;


Цитата(kuvshinka @  7.6.2011,  20:28 Найти цитируемый пост)

2. и наоборот - в, например, 12-ый бит переменной parametr записать "1"?

Код

ShortBitSet x;
x.asShort = ...;
x.bit12 = 1;

или из предыдущего примера
Код

setBit( x, 12, 1 );



Это сообщение отредактировал(а) borisbn - 8.6.2011, 09:53


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


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



kuvshinka, подобные вопросы следует задавать в разделе для новичков. Данный раздел по кроссплатформенным библиотекам.
PM   Вверх
kuvshinka
Дата 8.6.2011, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



мда....ну назначение операций  << и >> я знаю - побитовый сдвиг влево и вправо...а что делает (для чего нужна) операция "&" и  assert? 
PM MAIL   Вверх
borisbn
Дата 8.6.2011, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



& - побитовое "И"
Цитата

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1


assert нужен для того, чтобы убедиться в правильности/истинности выражения. В отладочной сборке при попадании в assert ложного выражения будет выдано сообщение с именем файла исходника и номером строки, где assert не сработал. Часто используется для того, чтобы убедиться в том, что переданный указатель не нулевой.
Код

void foo( int * p ) {
    assert( p );
    *p = 42;
}

согласись, что если p нулевой, то программа не должна делать запись/чтение по нему...


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


Опытный
**


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

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



ммм...
допустим есть short- число A
1.  если мне надо выделить из нее, допустим, 5-8 биты в отдельную переменную X, то это будет вроде как
Код

X=(A>>5)&0xF;

то есть надо сдвинуться вправо на 5 разрядов и...как трактовать умножение (&) на число 0xF (все единицы в 4-х выделяемых разрядах), вообще зачем его (&) здесь использовать? разъясните пож-та как-то "графически" что ли...
2. почему, если надо выделить разряд(ы), начиная со старшего (15-го), то достаточно только использовать сдвиг >> и не надо &?
если выделяю старшие 2 разряда (15 и 14), то это будет наверное так:
Код

X=A>>14

то есть достаточно (?) сдвинуть все вправо на 14 "ненужных" разрядов и не надо (...)&0x3...
PM MAIL   Вверх
volatile
Дата 8.6.2011, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(kuvshinka @  8.6.2011,  21:29 Найти цитируемый пост)
то есть надо сдвинуться вправо на 5 разрядов и...как трактовать умножение (&) на число 0xF 

трактовать так: обнулить все биты кроме четырех младших.
0xF = 0000000000001111

Цитата(kuvshinka @  8.6.2011,  21:29 Найти цитируемый пост)
если выделяю старшие 2 разряда (15 и 14), то это будет наверное так:
X=A>>14
то есть достаточно (?) сдвинуть все вправо на 14 "ненужных" разрядов и не надо (...)&0x3... 

В принципе, если число 16-разрядное, то не надо, потому-что там и так все биты уже обнулены.
Но во-первых, если завтра вы решите перейти на 32-разрядную версию, то программа ваша перестанет правильно работать.
а во-вторых &3 не помешает в любом случае, даже в 16-разрядной. Так что лучше использовать ее всегда.

Добавлено через 1 минуту и 50 секунд
Цитата(borisbn @  8.6.2011,  05:56 Найти цитируемый пост)
template< typename T >
...

borisbn, я это заберу, если не возражаете. пригодиться. smile

Добавлено через 4 минуты и 5 секунд
тьфу-ты. опять мягкий знак.... smile 
PM MAIL   Вверх
volatile
Дата 9.6.2011, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(volatile @  8.6.2011,  23:46 Найти цитируемый пост)
В принципе, если число 16-разрядное, то не надо, потому-что там и так все биты уже обнулены.

Тут надо уточнить, если число 16-разрядное, и беззнаковое
В случае если используется знаковое (signed) число, а в вашем первом вопросе именно знаковое и используется, то делать битовый энд (&) обязательно, потому-что при сдвиге вправо, для знакового числа, копируется самый старший (знаковый) бит.

kuvshinka, короче.
Цитата(volatile @  8.6.2011,  23:46 Найти цитируемый пост)
&3 не помешает в любом случае, даже в 16-разрядной. Так что лучше использовать ее всегда.

 smile 

Это сообщение отредактировал(а) volatile - 9.6.2011, 00:36
PM MAIL   Вверх
borisbn
Дата 9.6.2011, 05:11 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



>я это заберу, если не возражаете.
LGPL smile 


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


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Цитата(kuvshinka @  8.6.2011,  21:29 Найти цитируемый пост)
то есть надо сдвинуться вправо на 5 разрядов и...как трактовать умножение (&) на число 0xF (все единицы в 4-х выделяемых разрядах), вообще зачем его (&) здесь использовать? разъясните пож-та как-то "графически" что ли...

Не надо трактовать & как умножение! Преподаватели называют логическую операцию И умножением только потому, что:
1. в логике только два числа: 0 и 1 (false и true)
2. поведение & полностью соответствует умножению для этого набора чисел (повторяю 0 и 1), но если у тебя возможно 1 & 10, то это уже не умножение!!!

У тебя же используется побитовое И.
Итак, твой код: x = (A >> 5) & 0x0f;
Битовая математика:
Код
Saaaaaaaaaaaaaaa : A
sssssSaaaaaaaaaa : A >> 5 (если бы A было unsigned short, то вместо s был бы 0)
000000000000aaaa : (A >> 5) & 0x0f


PM   Вверх
Dem_max
Дата 9.6.2011, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 4
Всего: 39



Код

typedef struct _BITS
{
   int bit0: 1;
   int bit1: 1;
   int bit2: 1;
   int bit3: 1;
   int bit4: 1;
   int bit5: 1;
   int bit6: 1;
   int bit7: 1;
} SBITS;
 
typedef union _BYTE
{
   unsigned char BYTE;
   SBITS BITS;
 
   operator [] (int i)
   {
      switch(i){
         case 0: return BITS.bit0;
         case 1: return BITS.bit1;
         case 2: return BITS.bit2;
         case 3: return BITS.bit3;
         case 4: return BITS.bit4;
         case 5: return BITS.bit5;
         case 6: return BITS.bit6;
         case 7: return BITS.bit7; 
      }
   }
} REGISTR;
 
REGISTR R0, R1, R2, R3;
 
int main()
{
      R0.BYTE = 0x00;
      int g = R0.BITS[1];
      R0.BITS.bit5 = 1;
      printf("Write R0 = %X", R0.BYTE);
      WritePort(R0.BYTE);
      R0.BYTE = ReadPort();
      printf("Read R0 = %X", R0.BYTE);
      WritePort(R0.BYTE);
      decode(R0)
}



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
kuvshinka
Дата 11.6.2011, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



borisbn:
Ваш пример я вроде поняла - битовое поле и объединение этого поля с short-переменной
Код

union ShortBitSet {
  struct {
      unsigned short bit0 : 1;
      unsigned short bit1 : 1;
      unsigned short bit2 : 1;
      unsigned short bit3 : 1;
      unsigned short bit4 : 1;
      unsigned short bit56 : 2;
      unsigned short bit7 : 1;
      unsigned short bit8 : 1;
      unsigned short bit9 : 1;
      unsigned short bit10 : 1;
      unsigned short bit11 : 1;
      unsigned short bit12 : 1;
      unsigned short bit13 : 1;
      unsigned short bit14 : 1;
      unsigned short bit15 : 1;
  };
  unsigned short asShort;
};

а как этот пример адаптировать под массив считываемых данных (в данном случае типа short)? (то есть можно ли также использовать массив битовых полей+массив short данных)???
как такой пример будет выглядеть?
PM MAIL   Вверх
borisbn
Дата 11.6.2011, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(kuvshinka @  11.6.2011,  22:27 Найти цитируемый пост)
можно ли также использовать массив битовых полей+массив short данных

конечно.
Код

ShortBitSet array[ 10 ];
short * p = (short*)array;
read_откуда_нибудь( p, 10 );

или так
Код

ShortBitSet array[ 10 ];
for ( int i = 0; i < 10; i++ ) {
    read_откуда_нибудь( &array[ i ].asShort, 1 );
}

запись точно также
Код

ShortBitSet array[ 10 ];
// заполнение array
const short * p = (const short*)array;
write_куда_нибудь( p, 10 );

или так
Код

ShortBitSet array[ 10 ];
for ( int i = 0; i < 10; i++ ) {
    write_куда_нибудь( array[ i ].asShort, 1 );
}




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


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

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


 




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


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

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