Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

OR, AND, вычисление флагов [D6]


VLS1 ©   (2007-02-13 22:02:00) 

У меня есть некая Word-овое значение, например $2004, само это значение -- это общий флаг, который получается путём OR-ования входящих составляющих ну т.е. например

 PrjConst_MySQLReqUser = $2000;
 PrjConst_MySQLReqHead = $0004;


 соответственно $2000 OR $0004 = $2004.

 Обратно проверяется опять же по подобной схеме

 Value = $2004;
 if (Value and PrjConst_MySQLReqUser) = PrjConst_MySQLReqUser then ....


 А теперь нужно определить исходя из всех флагов которые у нас присутствуют ($2000, $0004, ...), определить, какие не присутствуют в этом списке.
 Поясню

 Есть значение:
 $2807, из них $2000 и $0004 нам известны, а вот остельные:

 $0800
 $0001
 $0002

 не известны.

 Каким образом отделить и определить эти самые не известные?

 Пытался что-то соорудить но дело заглозло на цикле.

 MySQLReqTypes: array [0.. bla] of Integer = (,PrjConst_MySQLReqUser, .....);
 ReqTypeVal: Word;

 ReqTypeVal := Value;
 for i := Low(MySQLReqTypes) to High(MySQLReqTypes) do
   if (MySQLReqTypes[i] and Value) = MySQLReqTypes[i] then
//     ReqTypeVal := ReqTypeVal
   .....


evvcom   (2007-02-14 12:25:00) [1]

> [7] Сергей М. ©   (14.02.07 12:22)

Опередил, со множествами :)


evvcom   (2007-02-14 12:24:00) [2]

Сделай через множества, проще будет.
type
 TMySetValue = (Req0, Req1, ReqHead, Req3, ..., Req12, ReqUser, Req14, Req15);
 TMySet = set of TMySetValue;
...
Value = $2004;
if ReqUser in TMySet(Value) then ...
Value = $2807;
for SetValue := Low(TMySetValue) to High(TMySetValue) do
 if SetValue in TMySet(Value) then ...

И никаких сдвигов, всю эту арифметику за тебя посчитает компилятор.


Сергей М.   (2007-02-14 12:22:00) [3]


> VLS1   (14.02.07 12:10) [5]


Вероятно под SHL в виду имелся не Паскаль-оператор, а ассемблерная инструкциия. Оба оператора логически эквивалентны, с той лишь разницей, что в ассемблерном блоке после shl можно тут же проанализировать флаг CF, где хранится значение вытолкнутого разряда сдвигаемого значения.

Если уж на то пошло, то уместней будет использовать DIV и MOD.

Ну а с точки зрения удобочитаемости кода еще уместней будет рассматривать это значение как множество, правда для этого придется для каждой маски в наборе флагов определить константу со значением порядкового номера соотв.бита


begin...end   (2007-02-14 12:18:00) [4]

> VLS1   (14.02.07 12:10) [5]

var
 Value: Word;
 I: Integer;
begin
 Value := $0803;
 for I := 0 to 15 do
 begin
   if Odd(Value) then
     ShowMessageFmt('Найден флаг: $%.4x', [1 shl I]);
   Value := Value shr 1
 end
end


VLS1   (2007-02-14 12:10:00) [5]

С моим запасом знаний "логических операций", я просто откровенный тупица. Ничего не понял.

Ну вот есть у нас: $0803. Сдвинем по SHR, - получим: $0401, ещё раз сдвинем получим: $0200 и т.д. Т.е. я не понимаю что нужно учитывать, смотреть и т.д. при shr 1 - мы делим на 2, при shl - умножаем. ...

Я ничего не придумал. Может можно показать примером для моего случая?


Desdechado   (2007-02-14 10:45:00) [6]

SHL\SHR - сдвиг битов в числе
можно сдвигать на 1 и сравнивать, изменилось ли значение
исходя из этого можно делать выводы, запоминая на сколько сдвигал (это же степени двойки)


VLS1   (2007-02-14 10:26:00) [7]

Ок, спасибо, действительно с помощью ксора получил. Т.е. после всего у меня осталось $0803.

А как определить неизвестные используя SHL, пока не додумался, что подскажете?


Германн   (2007-02-13 22:43:00) [8]

А для определения неизвестных пригодится операция SHL.


Desdechado   (2007-02-13 22:13:00) [9]

Для этого есть битовая операция XOR.
Ксоришь со всеми известными тебе, остаются неизвестные.


Наверх

Титульная страница Поиск, карта сайта Написать письмо