-
И немного отходя от темы получения доступа к биту:
Не рекомендуется использовать в условиях исполнимые выражения поскольку это усложняет отладку.
В данном конкретном случае все предельно ясно
Код:
IF IsClear (x, y) THEN
....
END_IF
И если программа не заходит внутрь условия, то понятно, почему она этого не сделала
но в случае
Код:
IF IsClear (x, y) OR IsClear (x, y + 1) THEN
....
END_IF
Уже сложнее понять какое же из условий не выполняется и почему программа не зашла внутрь условия.
Поэтому рекомендуется ввести дополнительную переменную с "говорящим" именем, которую затем использовать в условии.
Например:
Код:
VAR
// Признак того, что активна авария "ПОЖАР"
xIsFireAlarmActive : BOOL;
// Признак того, что активна авария датчика
xIsSensorAlarmActive : BOOL;
END_VAR
xIsFireAlarmActive := IsClear (x, y);
xIsSensorAlarmActive := IsClear (x, y + 1);
IF xIsFireAlarmActive OR xIsSensorAlarmActive THEN
....
END_IF
В таком случае при отладке всегда будет понятно, почему программа не зашла внутрь условия.
-
Да у меня совсем не такая ситуация была. Надо было преобразовать часть битов в массиве в массив логических для дальнейшего удобства. Там только 10 младших битов в слове были значащими, поэтому пришлось сделать так
Код:
FOR i:=1 TO stECOState.byLampsQty DO
stECOState.arbLampState[i]:=NOT(GetBitWord(arwData[i/10],(i MOD 10)-1));
END_FOR
И функция совсем другое у меня делает, вчера не был рядом с этой прогой. Но смысл тот же, нужно было знать бит по переменной, а не по константе.
Про extract не знал, вообще в библиотеку util не заглядывал. Сейчас вот заглянул и вот как выглядит эта функция
Код:
EXTRACT:=((SHR(X,N) AND 1)=1);