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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> двоичная логика. исключить X из Y. 
V
    Опции темы
boostcoder
Дата 26.12.2011, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



всем привет.

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

имеется такой код:
Код

#include <iostream>

enum mye {
   one = 0x02,
   two = 0x04,
   three = 0x08
};

void test( int arg) {
   if ( arg & one ) {
      std::cout << "one ";
   }
   if ( arg & two ) {
      std::cout << "two ";
   } 
   if ( arg & three ) {
      std::cout << "three ";
   }
   
   std::cout << std::endl;
}

int main() {
   test(one);
   test(two);
   test(two|one);
   test(two|three);
   test(one|three);
   test(one|three|two);
}

http://liveworkspace.org/code/c8c0c8130812...b66bc14a01b8a91

в этом коде мне не нравится то, что в функции test() для обработки аргумента необходимо писать if для всех членов определенного енума.
вопроса два:
1. каким образом можно записать это в виде цикла так, чтоб в цикле перебрать и проверить все комбинации?
2. что нужно сделать с аргументом для того чтоб его можно было передать в switch() ?

благодарен.
PM WWW   Вверх
kuzulis
Дата 26.12.2011, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



А ничего тут и не сделать особо. Текущий вариант самый быстрый и правильный, ИМХО.
Всякие циклы и т.п. только загромоздят.

Можно на крайняк так:

Код

enum mye {
   one = 0x02,
   two = 0x04,
   three = 0x08
};

void test( int arg) {
    int i = 1;
    do {
        arg >>= i++;
        if (arg & 1)
            std::cout << i;
    } while (arg);
}



Это сообщение отредактировал(а) kuzulis - 26.12.2011, 21:18
PM MAIL   Вверх
feodorv
Дата 26.12.2011, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Так подойдёт?

Код

#include <iostream>

const unsigned int start = 1;
const unsigned int end = 4;

const char *names[] =
{
  "one ",
  "two ",
  "three ",
  NULL
};

void test( unsigned int arg) {
   for( unsigned int i = start; i < end; i++)
      if( arg & (0x1u<<i) ) {
         std::cout << names[i-start];
      }
   std::cout << std::endl;
}

enum mye {
   one = 0x02,
   two = 0x04,
   three = 0x08
};

int main() {
   test(one);
   test(two);
   test(two|one);
   test(two|three);
   test(one|three);
   test(one|three|two);
}


Это сообщение отредактировал(а) feodorv - 26.12.2011, 21:36


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
boostcoder
Дата 26.12.2011, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



kuzulis, feodorv, неее, рыбятушки. что-то это все не то. у меня было два вопроса. ответ на первый я почти получил. но и он какой-то не логичный, как мне кажется..

вот я упаковываю значения при помощи |(or). в результате, я получаю что-то типа множества. я полагал, что по этому множеству можно как-то проитерироваться. не?

Добавлено @ 22:18
feodorv, не могли бы Вы словами рассказать, что тут происходит?:
Цитата(feodorv @  26.12.2011,  21:31 Найти цитируемый пост)
arg & (0x1u<<i)



Это сообщение отредактировал(а) boostcoder - 26.12.2011, 22:35
PM WWW   Вверх
feodorv
Дата 26.12.2011, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(boostcoder @  26.12.2011,  22:16 Найти цитируемый пост)
у меня было два вопроса

Цитата(boostcoder @  26.12.2011,  20:47 Найти цитируемый пост)
что нужно сделать с аргументом для того чтоб его можно было передать в switch()

Вопрос я совсем не понял, даже приблизительно. Была надежда, что из ответа на первый можно будет вывести второй, но нет)))

Цитата(boostcoder @  26.12.2011,  22:16 Найти цитируемый пост)
не могли бы Вы словами рассказать, что тут происходит?

Происходит побитовый сдвиг влево изначальной единички на нужное число позиций:
Код

0x1u << 0 даёт 0x1u
0x1u << 1 даёт 0x2u
0x1u << 2 даёт 0x4u
0x1u << 3 даёт 0x8u


Цитата(boostcoder @  26.12.2011,  22:16 Найти цитируемый пост)
по этому множеству можно как-то проитерироваться

Вот как раз и происходит обход всех возможных битов smile

Добавлено через 4 минуты и 33 секунды
Цитата(boostcoder @  26.12.2011,  20:47 Найти цитируемый пост)
что нужно сделать с аргументом для того чтоб его можно было передать в switch()

Аааа smile Возможно, я понял:
Код

int i;
if( arg == 0 ) return ???;
for( i = 0; i < 32; i++) if( arg & (0x1u << i) ) break;
switch( i )
{
  case 0:
    ...
  case 1:
    ...
}


Добавлено через 8 минут и 57 секунд
Или:
Код

int i = 0;
while( (arg & 0x1u) == 0 ){ arg >>= 1; i++; }

Только тут уж железно arg на 0 предварительно проверить нужно.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
newbee
Дата 26.12.2011, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


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

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



Если сложно вдуплить битовые сдвиги, можно запихать все возможные маски в массив и пройтись по нему.

Код

x=011100001
masks={one,two,four,...}
foreach(m in masks)
 if(x&m)
  std::cout<<m


Выше я очень бегло посмотрела примеры, как-то сложно...

Код

x=0001010110
for(size_t i=1;;i=i<<1){ // сдвигаем i на один бит, из 1 получаем 2, из 2 - 4, из 4 - 8 и т.д.
 if(x&i)
  std::cout<<i;
 if(i==last_mask) // проверяем i на значение самой "большой" маски
  break;}



--------------------
You're face to face
With man who sold the world
PM   Вверх
mes
Дата 27.12.2011, 02:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  26.12.2011,  19:47 Найти цитируемый пост)
. каким образом можно записать это в виде цикла так, чтоб в цикле перебрать и проверить все комбинации?


boostcoder, 
http://cplusplus.com/reference/stl/bitset/test/
или
http://cplusplus.com/reference/stl/bitset/operator[]/

в дополение :
http://cplusplus.com/reference/stl/bitset/count/
http://cplusplus.com/reference/stl/bitset/any/
http://cplusplus.com/reference/stl/bitset/none/


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


pattern`щик
****


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

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



mes, не нужен мне битсет.

всем спасибо. сейчас попробую все это дело усвоить...
PM WWW   Вверх
mes
Дата 28.12.2011, 01:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  27.12.2011,  19:38 Найти цитируемый пост)
, не нужен мне битсет.

может и не нужен, но может служить выходом для тех, кому трудно обращаться с битами..
ваш первый пример : http://liveworkspace.org/code/6d76dce75302...a78172b15ba5b99


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


pattern`щик
****


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

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



Цитата(mes @  28.12.2011,  01:42 Найти цитируемый пост)
может служить выходом для тех, кому трудно обращаться с битами..

ну так я пытаюсь разобраться, а Вы меня обратно, в мое же болото smile
PM WWW   Вверх
mes
Дата 28.12.2011, 02:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  28.12.2011,  01:04 Найти цитируемый пост)
ну так я пытаюсь разобраться, а Вы меня обратно, в мое же болото 

ну разбирайтесь, однако с битсетом иногда надежнее )




--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0534 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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