Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Побитовое или


Автор: DESert 7.12.2005, 23:20
Привет всем!
Как посчитать "побитое или" двух целых чисел?...
Каков результат этой оперции?
Заранее благодарен smile

Автор: bel_nikita 7.12.2005, 23:25
Переведи в двоичную, а дальше:
1 | 1 = 1
1 | 0 = 1
0 | 0 = 0

Автор: nikitao 7.12.2005, 23:26
Вот так и будет:
Код

int x,y,z;
x=17;
y=20;
z=x|y;//побитовое или x и y

Автор: DESert 7.12.2005, 23:36
тогда z равно 20 (10100) ? если правильно всё понял...

Автор: nikitao 7.12.2005, 23:40
DESert,При компеляции выдало 21.Ты ошибся в последнем бите

Автор: DESert 7.12.2005, 23:49
да, устный счет подвёл, машина оказалась сильней smile

Автор: cardinal 7.12.2005, 23:58
DESert, не забывай, что проверить это можно в обычном виндовозном калькуляторе...

Автор: DESert 8.12.2005, 00:10
а как можно представить число типа double в двоичное представление?

Автор: cardinal 8.12.2005, 00:18
Точно также как и все остальные...
http://forum.vingrad.ru/index.php?act=Search&CODE=show&searchid=e52422d09ad6cb98f29ad4614aa4c715&search_in=posts&result_type=topics&highlite=%F1%F7%E8%F1%EB%E5%ED%E8%FF

Автор: DESert 8.12.2005, 00:45
спасибо smile

Автор: Fighter 12.12.2005, 00:05
А как работать с побитовыми операциями, например, как это широко практикуется в MFC.
Например в каком нибудь *.h файле объявлены константы

Код

#define WS_VISIBLE 0x0001
#define WS_FLAT      0x0002
...


Потом в какой-нибудь функции мы пишем

Код

  CreateWindow(...., WS_VISIBLE | WS_FLAT, ...)


И у нас создается "видимое плоское окошко".
Как самому писать такие фени (ну пусть что-нить попроще будет для начала).
Например, чтобы я написал что-то вроде

Код

  #define PARAM1 0x0001
  #define PARAM2 0x0002

...
  int a;
  a = PARAM1 | PARAM2;


Вроде я правильно все написал (если не правильно то пожалуйста поправльте). И затем мне нужно проверять, установил ли я значения PARAM1 и PARAM2 или нет.

Автор: cardinal 12.12.2005, 03:33
Цитата(Fighter @ 11.12.2005, 22:05)
И затем мне нужно проверять, установил ли я значения PARAM1 и PARAM2 или нет.

А если ты их не установишь, то ничего компилироваться не будет...
Цитата(Fighter @ 11.12.2005, 22:05)
например, как это широко практикуется в MFC.

Широко, т.к. то что ты объявляешь с помощью #define это константы, а их название запомнить проще, чем какие-то там цифры.
Цитата(Fighter @ 11.12.2005, 22:05)
Как самому писать такие фени (ну пусть что-нить попроще будет для начала).
Например, чтобы я написал что-то вроде

Ну так правильно ты все написал. В чем проблема то?

Автор: azesmcar 12.12.2005, 09:29
Например для функции
Код

#define PARAM1 0x0001
#define PARAM2 0x0002

int func(int params)
{
   if ( (params & PARAM1) != 0 )
   {
       //флаг PARAM1 задан
   }
   if ( (params & PARAM2) != 0 )
   {
       //флаг PARAM2 задан
   }
}

Работает это так..
ты задаешь вместо своей переменной int params PARAM1 | PARAM2 т.е. получается
00000001 PARAM1
|
00000010 PARAM2
-------------
00000011 params
а в функции уже проверяешь если последний бит установлен в единицу значит PARAM1 задан...примерно так
00000011 params
&
00000001 PARAM1
-------------
00000001 result

Автор: apook 1.10.2007, 08:15
передаю  PARAM1 проверяю: params & PARAM1 ==1
передаю  PARAM2 проверяю: params & PARAM2 ==2

передаю  PARAM2 проверяю: params & PARAM1 ==0
передаю  PARAM1 проверяю: params & PARAM2 ==0
все верно
передаю  PARAM2 проверяю: params & PARAM3 ==2
передаю  PARAM3 проверяю: params & PARAM2 ==2
что-за? как сделать больше двух параметров

Код

#define PARAM1 0x0001
#define PARAM2 0x0002
#define PARAM3 0x0003 //?



Автор: dumb 1.10.2007, 08:34
Цитата(apook @  1.10.2007,  09:15 Найти цитируемый пост)
что-за? как сделать больше двух параметров
константы должны быть степенями двойки: 1,2,4,8,...

Автор: Fazil6 1.10.2007, 08:35
Цитата

пить надо меньше, меньше надо пить...



Автор: zkv 1.10.2007, 18:37
Цитата(Fighter @  12.12.2005,  00:05 Найти цитируемый пост)
Как самому писать такие фени (ну пусть что-нить попроще будет для начала).
Например, чтобы я написал что-то вроде
  #define PARAM1 0x0001
  #define PARAM2 0x0002
...
  int a;
  a = PARAM1 | PARAM2;


Как правильно сказал dumb, все дело в волшебных пузырьках - степенях двойки smile
Посмотрим, как записываются числа - степени двойки в двоичной системе:
2^x  |  x(dec)  |  x(bin)  |
-------------------------------
2^0  |   1         |1           |
2^1  |   2         |10         |
2^2  |   4         |100       |
2^3  |   8         |1000     |
2^4  |   16       |10000   |
...

вообщем видна закономерность?  smile
те с помощью числа 2^0 можно манипулировать младшим битом в числе (обычно - самый правый бит), 
2^1 - вторым справа и так далее с помощью логических операций. 

Для установки бита пользуемся оператором | 
Смотрим таблицу:
Цитата(bel_nikita @  7.12.2005,  23:25 Найти цитируемый пост)
1 | 1 = 1
1 | 0 = 1
0 | 0 = 0 

еще надо было добавить строку: 0 | 1 = 1
берем любое число A, и применяем к нему операцию:
A |= 1;
в итоге все биты числа A останутся без изменений, кроме правого, который установится в 1, независимо от того, был установлен в нем бит или нет ранее.
Почему так - понятно по таблице выше.

Для сброса бита используем оператор &
Таблица:
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0 
применяем операцию:
A &= 1111..10; - колличество разрядов соответствующее числу A, 
или другими словами:
A &= ~1; 
или 
A ^= 1; 

Для проверки бита:
(A & 1) != 0;

Примерчик:
Код

#include <iostream>

#define PARAM0 1
#define PARAM1 1<<1
#define PARAM2 1<<2
#define PARAM3 1<<3
#define PARAM4 1<<4
#define PARAM5 1<<5

bool IsParam3Set( unsigned nParams )
{
    nParams &= PARAM3;
    return nParams != 0;
}

void DropParam3( unsigned &nParams )
{
    nParams ^= PARAM3;
}

void SetParam3( unsigned &nParams )
{
    nParams |= PARAM3;
}

void PrintParam3State( unsigned nParams )
{
    if( IsParam3Set(nParams) )
        std::cout<<"set";
    else
        std::cout<<"dropped";
}

int main()
{
    unsigned nParams = 0;
    std::cout<<"Parameter 3 is initially ";
    PrintParam3State( nParams );

    SetParam3( nParams );
    std::cout<<"\nParameter 3 after setting is ";
    PrintParam3State( nParams );

    DropParam3( nParams );
    std::cout<<"\nParameter 3 after dropping is ";
    PrintParam3State( nParams );

    std::cout<<"\nPress <Enter> to continue...";
    std::cin.get();
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)