Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Двоичное вычитание числа из объединения чисел


Автор: Ciber SLasH 25.3.2006, 11:17
Что-то я никак не въеду как вычесть число из объединения чисел?
К примеру, воьзьмём двоичные числа. Есть 2 числа:
1) 1100
2) 0110
объединяем эти два числа: 1100 or 0110 = 1110
как теперь из результат исключитьпервое число, чтобы осталось второе? При условии, что объединение может включать различные комбинации чисел, т.е. может быть: 1100 or 0110 or 1000 ... or xxxx и нужно при некотором условии или добавить число в объединение или исключить, но чтобы другие числа можно было бы проверить (результат and число == число).

Автор: sdeniss 26.3.2006, 10:26
xor 2 число не подойдет?
a or b xor b = a or 0 = a

Автор: Ciber SLasH 26.3.2006, 17:23
Цитата(sdeniss @ 26.3.2006, 10:26 Найти цитируемый пост)
xor 2 число не подойдет?

Не получится так.
Вот смотри: 1100 or 0110 = 1110
Теперь xor-им результат на первое число: 1110 xor 1100 = 0010 (не равно второму числу)
Не получается xor-ом получить второе число из результата.

Автор: cardinal 26.3.2006, 18:47
Цитата(Ciber SLasH @ 25.3.2006, 09:17 Найти цитируемый пост)
Что-то я никак не въеду как вычесть число из объединения чисел?

А почему объединение это or?

Автор: DENNN 26.3.2006, 19:19
Цитата(Ciber SLasH @ 25.3.2006, 11:17 Найти цитируемый пост)
объединяем эти два числа: 1100 or 0110 = 1110
как теперь из результат исключитьпервое число, чтобы осталось второе?

Никак. После логического ИЛИ вобщем случае это невозможно (в отличие от XOR).

Автор: Бегемот 26.3.2006, 20:42
Ciber SLasH, ну, а если ничего не вычислять, а просто сохранить нужные значения до того как произведёшь объединение?! А в случае ЧАВО - восстановить попорченное число!

Автор: nworm 26.3.2006, 20:46
Цитата

Никак. После логического ИЛИ вобщем случае это невозможно (в отличие от XOR).


Да, нельзя. Но кое-что восстановить можно.
Это ясно сразу из определения "or":

X Y | Z = X or Y
0 0 | 0
0 1 | 1
1 0 | 1
1 1 | 1

Тогда

Y Z | X = f(Y,Z)
0 0 | 0
0 1 | 1
1 0 | невозможно
1 1 | 0 или 1

Автор: Ciber SLasH 27.3.2006, 13:20
Вобщем я всё это спрашивал для того чтобы понять как исключается стиль из функции GetWindowLong.

Вот есть к примеру окно (с хэндлом Wnd), узнаём его стили:
Код
Style := GetWindowLong(Wnd, GWL_STYLE);

Чтобы исключить из этого окна какой-то стиль (к примеру WS_CAPTION), мы делаем следущее:
Код
SetWindowLong(Wnd, GWL_STYLE, Style and not WS_CAPTION);

А как работает алгоритм исключения не понятно? Ведь функция GetWindowLong возвращает 16-битное число, в котором определённые биты отвечают за стиль окна.

Автор: cardinal 27.3.2006, 14:10
and not в данном случае обнуляет 1 в 16-битно числе в нужном месте и все... Или я ошибаюсь?

Автор: Ciber SLasH 27.3.2006, 15:04
Цитата(cardinal @ 27.3.2006, 14:10 Найти цитируемый пост)
and not в данном случае обнуляет

Верно.
Короче я понял алгоритм этой функции. Вся соль в том, что каждый бит этого слова отвечает за определённый стиль окна. И поэтому ничего исключать здесь не надо, — надо всего лишь обнулить бит.

Тогда мне бы подошло множество. Из множества можно исключать значения. Но к сожаления в Delphi нельзя определить такое множество: var MN: set of Integer;

Автор: nworm 27.3.2006, 16:05
А какая цель-то всего этого? Чем не устраивает имеющийся способ?

Автор: Ciber SLasH 27.3.2006, 16:17
Цитата(nworm @ 27.3.2006, 16:05 Найти цитируемый пост)
А какая цель-то всего этого?

К примеру отлов нажатий клавиш. Когда срабатывает hook, то нужно проверить, нужно ли блокировать эту клавишу или нет. И ещё есть функция, которая добавляет/исключает ту или иную клавишу из наблюдения.

Я сначала хотел описать множество, в которое бы добавлялась нужная клавиша, если надо её отловить или удалялась эта клавиша, если не надо её отлавливать.
К примеру:
Код

var
  MN: set of Integer;
begin
  include(MN, VK_INSERT);  // отлавливать Insert
  include(MN, VK_CAPITAL);  // отлавливать CapsLock
end.

есть также процедура, которая исключает/добавляет клавишу:
Код

procedure IgnoreKey(isIgnore: Boolean; Key: Integer);
begin
  if isIgnore then exclude(MN, Key)
  else include(MN, Key)
end;

и есть процедура отлова клавиш, которая проверяет клавишу на вхождение в множество:
Код

if sReturn^.wParam in MN then
begin
  // клавиша входит в множество, значит её нужно блокировать
end
else
  // блокировать не нужно

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