Битовые операции — различия между версиями
(Отметить эту версию для перевода) |
|||
Строка 1: | Строка 1: | ||
<translate> | <translate> | ||
− | === Битовые операции === | + | === Битовые операции === <!--T:1--> |
− | ==== Удобные битовые операции ==== | + | ==== Удобные битовые операции ==== <!--T:2--> |
Можно определить несколько удобных битовых операций, помня о том что в lua биты нумеруются с 1. Ссылка взята [http://lua-users.org/wiki/BitwiseOperators отсюда], там же есть и другие полезные функции. | Можно определить несколько удобных битовых операций, помня о том что в lua биты нумеруются с 1. Ссылка взята [http://lua-users.org/wiki/BitwiseOperators отсюда], там же есть и другие полезные функции. | ||
+ | <!--T:3--> | ||
<syntaxhighlight lang = lua> | <syntaxhighlight lang = lua> | ||
+ | <!--T:4--> | ||
function bit(n) | function bit(n) | ||
return 2 ^ (n - 1) -- возвращает число - вес разряда номер n | return 2 ^ (n - 1) -- возвращает число - вес разряда номер n | ||
end | end | ||
+ | <!--T:5--> | ||
function hasbit(x, p) | function hasbit(x, p) | ||
return x % (p + p) >= p -- возвращает состояние бита p как true/false; if hasbit(value, bit(2)) then ... | return x % (p + p) >= p -- возвращает состояние бита p как true/false; if hasbit(value, bit(2)) then ... | ||
end | end | ||
+ | <!--T:6--> | ||
function setbit(x, p) | function setbit(x, p) | ||
return hasbit(x, p) and x or x + p -- установить бит № p в х Пример использования: х = setbit(х, bit(p)) | return hasbit(x, p) and x or x + p -- установить бит № p в х Пример использования: х = setbit(х, bit(p)) | ||
end | end | ||
+ | <!--T:7--> | ||
function clearbit(x, p) | function clearbit(x, p) | ||
return hasbit(x, p) and x - p or x -- тоже только снять бит | return hasbit(x, p) and x - p or x -- тоже только снять бит | ||
Строка 24: | Строка 29: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | ==== Преобразование битовой таблички в число ==== | + | ==== Преобразование битовой таблички в число ==== <!--T:8--> |
Данная функция может быть полезна для нестандартных преобразований, когда число хранится в специфичном формате и его необходимо обработать по частям, используя заданную позицию 1-го бита и длину поля значения. | Данная функция может быть полезна для нестандартных преобразований, когда число хранится в специфичном формате и его необходимо обработать по частям, используя заданную позицию 1-го бита и длину поля значения. | ||
+ | <!--T:9--> | ||
<syntaxhighlight lang = "lua"> | <syntaxhighlight lang = "lua"> | ||
+ | <!--T:10--> | ||
function getNumberFromTab(tab,start,length) -- получить число из таблички | function getNumberFromTab(tab,start,length) -- получить число из таблички | ||
local result_str = ""; | local result_str = ""; | ||
Строка 38: | Строка 45: | ||
end -- getNumberFromTab | end -- getNumberFromTab | ||
+ | <!--T:11--> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | ==== Преобразование числа в битовую табличку ==== | + | ==== Преобразование числа в битовую табличку ==== <!--T:12--> |
+ | <!--T:13--> | ||
В lua (в версии, используемой в WebHMI) нет встроенной операции получения строкового представления двоичного числа. | В lua (в версии, используемой в WebHMI) нет встроенной операции получения строкового представления двоичного числа. | ||
Однако эта функция очень полезна в пользовательсиких протоколах и др. задачах, где требуется перераспределить или каким то образом обработать отдельные биты числа. | Однако эта функция очень полезна в пользовательсиких протоколах и др. задачах, где требуется перераспределить или каким то образом обработать отдельные биты числа. | ||
Текст варианта такой функции: | Текст варианта такой функции: | ||
+ | <!--T:14--> | ||
<syntaxhighlight lang = "lua"> | <syntaxhighlight lang = "lua"> | ||
+ | <!--T:15--> | ||
function getBits(input_num,length) -- работает с заданной длиной | function getBits(input_num,length) -- работает с заданной длиной | ||
Строка 68: | Строка 79: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | <!--T:16--> | ||
Далее можно переставить нужные биты местами и т.п. и получить нужное число. Ниже приведен пример перестановки битов 31 и 23 битов (при нумерации битов с 0) в ответе счетчика расходомера ВЛР 2301/2304 производства Асвега-У | Далее можно переставить нужные биты местами и т.п. и получить нужное число. Ниже приведен пример перестановки битов 31 и 23 битов (при нумерации битов с 0) в ответе счетчика расходомера ВЛР 2301/2304 производства Асвега-У | ||
+ | <!--T:17--> | ||
<syntaxhighlight lang = "lua"> | <syntaxhighlight lang = "lua"> | ||
function main (userId) | function main (userId) | ||
Строка 83: | Строка 96: | ||
WriteReg(1, tonumber(table.concat(bitTable),2)); | WriteReg(1, tonumber(table.concat(bitTable),2)); | ||
+ | <!--T:18--> | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | ==== Обработка чисел с плавающей точкой двойной точности ==== | + | ==== Обработка чисел с плавающей точкой двойной точности ==== <!--T:19--> |
+ | <!--T:20--> | ||
Некоторые устройства могут хранить данные в формате с повышенной точностью double float. В WebHMI текущей версии поддерживаются только 32 битные регистры, поэтому чтобы обработать 64 битное число необходимо будет использовать скрипт, которые "сцепит" два регистра в исходное число, а затем преобразует и запишет в обратно в float. Регистры должны быть типа double uint. | Некоторые устройства могут хранить данные в формате с повышенной точностью double float. В WebHMI текущей версии поддерживаются только 32 битные регистры, поэтому чтобы обработать 64 битное число необходимо будет использовать скрипт, которые "сцепит" два регистра в исходное число, а затем преобразует и запишет в обратно в float. Регистры должны быть типа double uint. | ||
Для "сцепки" чисел можно использовать описанную выше функцию getBits чтобы получить 2 таблицы, а затем дополнить первую таблицу битами из второй используя table.insert. В этом примере в качестве проверочного числа для простоты используется константа. | Для "сцепки" чисел можно использовать описанную выше функцию getBits чтобы получить 2 таблицы, а затем дополнить первую таблицу битами из второй используя table.insert. В этом примере в качестве проверочного числа для простоты используется константа. | ||
+ | <!--T:21--> | ||
<syntaxhighlight lang = "lua"> | <syntaxhighlight lang = "lua"> | ||
-------------------------------------- | -------------------------------------- | ||
Строка 97: | Строка 113: | ||
-------------------------------------- | -------------------------------------- | ||
+ | <!--T:22--> | ||
function main (userId) | function main (userId) | ||
-- получить результирующую табличку "0" "1" | -- получить результирующую табличку "0" "1" | ||
local result_tab = getBits(test_var,64); | local result_tab = getBits(test_var,64); | ||
+ | <!--T:23--> | ||
WriteReg(11,table.concat(result_tab)); -- отладочная печать в регстр - строку | WriteReg(11,table.concat(result_tab)); -- отладочная печать в регстр - строку | ||
+ | <!--T:24--> | ||
local result_num = 0.0; -- для хранения результата | local result_num = 0.0; -- для хранения результата | ||
+ | <!--T:25--> | ||
local sign,exp,mantissa = 0,0,0; | local sign,exp,mantissa = 0,0,0; | ||
local fraction_table = {}; -- табл. для дробной части | local fraction_table = {}; -- табл. для дробной части | ||
+ | <!--T:26--> | ||
-- определить знак | -- определить знак | ||
if result_tab[1] == "1" then | if result_tab[1] == "1" then | ||
Строка 128: | Строка 149: | ||
end | end | ||
+ | <!--T:27--> | ||
mantissa = mantissa +1; | mantissa = mantissa +1; | ||
DEBUG("m = "..tostring(mantissa)); -- отл. печать | DEBUG("m = "..tostring(mantissa)); -- отл. печать | ||
result_num = sign*(2^(exp - 1023))*mantissa; | result_num = sign*(2^(exp - 1023))*mantissa; | ||
+ | <!--T:28--> | ||
-- Обработка исключений | -- Обработка исключений | ||
if exp == 0 then -- subnormals | if exp == 0 then -- subnormals | ||
Строка 137: | Строка 160: | ||
end | end | ||
+ | <!--T:29--> | ||
if exp == 0x7ff then -- nan | if exp == 0x7ff then -- nan | ||
result_num = NaN; | result_num = NaN; | ||
Строка 143: | Строка 167: | ||
WriteReg(10, result_num); | WriteReg(10, result_num); | ||
+ | <!--T:30--> | ||
end -- main | end -- main | ||
+ | <!--T:31--> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | ==== Формирование общего регистра аварий по разным условиям ==== | + | ==== Формирование общего регистра аварий по разным условиям ==== <!--T:32--> |
+ | <!--T:33--> | ||
В WebHMI есть механизм аварий. Т.е. по состоянию бита в регистре можно автоматически генерировать записи в журнале о моменте возникновения, снятия аварии, квитировании ее оператором. | В WebHMI есть механизм аварий. Т.е. по состоянию бита в регистре можно автоматически генерировать записи в журнале о моменте возникновения, снятия аварии, квитировании ее оператором. | ||
+ | <!--T:34--> | ||
Однако в некоторых случаях использовать данный механизм непосредственно, как есть, может не совсем быть удобно. Например - аварийным считается определенный бит или их комбинация, разные коды ошибок (и их надо отличать друг от друга), значение больше или меньше порога и т.д. Если регистр имеет уже настроенные состояния для аварийной ситуации, используемое для отображения, то его нужно просто продублировать, выставив бит в общем аварийном регистре. Также может потребоваться введение задержки на срабатывание аварии, так как значение может иметь "дребезг" который надо фильтровать, прежде чем генерировать аварию в журнале. | Однако в некоторых случаях использовать данный механизм непосредственно, как есть, может не совсем быть удобно. Например - аварийным считается определенный бит или их комбинация, разные коды ошибок (и их надо отличать друг от друга), значение больше или меньше порога и т.д. Если регистр имеет уже настроенные состояния для аварийной ситуации, используемое для отображения, то его нужно просто продублировать, выставив бит в общем аварийном регистре. Также может потребоваться введение задержки на срабатывание аварии, так как значение может иметь "дребезг" который надо фильтровать, прежде чем генерировать аварию в журнале. | ||
Кроме этого удобнее, когда все аварии описаны в одном месте, а не разбросаны по сотням регистров. Т.е. рациональнее использовать один или несколько несколько 32-битных регистров для описания всех возможных аварий, и скрипт в котором эти аварии будут записываться в этот регистр по разным условиям. Ниже приведен пример такого скрипта: | Кроме этого удобнее, когда все аварии описаны в одном месте, а не разбросаны по сотням регистров. Т.е. рациональнее использовать один или несколько несколько 32-битных регистров для описания всех возможных аварий, и скрипт в котором эти аварии будут записываться в этот регистр по разным условиям. Ниже приведен пример такого скрипта: | ||
+ | <!--T:35--> | ||
Допустим, есть некая функциональная единица, например приточная вентиляционная установка, в которой есть некий общий признак аварии, есть несколько регистров с кодами текущих ошибок от частотных преобразователей и ситуация, когда один из регистров (влажность, СО2 и др.) вышел за допустимый диапазон, что является также аварийной ситуацией. | Допустим, есть некая функциональная единица, например приточная вентиляционная установка, в которой есть некий общий признак аварии, есть несколько регистров с кодами текущих ошибок от частотных преобразователей и ситуация, когда один из регистров (влажность, СО2 и др.) вышел за допустимый диапазон, что является также аварийной ситуацией. | ||
[[Файл:Alerts.png | 800px | left]] | [[Файл:Alerts.png | 800px | left]] | ||
<br clear = all> | <br clear = all> | ||
+ | <!--T:36--> | ||
Тогда скрипт, который обработает все эти ситуации и сформирует нужные флаги на своих местах может выглядеть так: | Тогда скрипт, который обработает все эти ситуации и сформирует нужные флаги на своих местах может выглядеть так: | ||
<syntaxhighlight lang = lua> | <syntaxhighlight lang = lua> | ||
Строка 167: | Строка 197: | ||
} | } | ||
+ | <!--T:37--> | ||
intAlertReg = "alertsReg" -- ОБЩИЙ РЕГИСТР АВАРИЙ | intAlertReg = "alertsReg" -- ОБЩИЙ РЕГИСТР АВАРИЙ | ||
+ | <!--T:38--> | ||
function main (userId) | function main (userId) | ||
+ | <!--T:39--> | ||
local alertInput, alertOut = 0,0 -- временные переменные для чтения аварий и формирования результата | local alertInput, alertOut = 0,0 -- временные переменные для чтения аварий и формирования результата | ||
local digit = 0 -- номер бита в исходном регистре, указывающий на аварию.. | local digit = 0 -- номер бита в исходном регистре, указывающий на аварию.. | ||
Строка 183: | Строка 216: | ||
+ | <!--T:40--> | ||
for j,k in pairs(v.bits) do -- выполнится по числу элементов в под-табличке bits | for j,k in pairs(v.bits) do -- выполнится по числу элементов в под-табличке bits | ||
-- проверяем тип операции - точное совпадение или другое условие | -- проверяем тип операции - точное совпадение или другое условие | ||
Строка 205: | Строка 239: | ||
end -- for bits inside | end -- for bits inside | ||
+ | <!--T:41--> | ||
end -- for allAlerts | end -- for allAlerts | ||
-- теперь просто записать то что получилось в общий регистр аварий | -- теперь просто записать то что получилось в общий регистр аварий | ||
WriteReg(intAlertReg, alertOut) | WriteReg(intAlertReg, alertOut) | ||
+ | <!--T:42--> | ||
end -- main | end -- main | ||
+ | <!--T:43--> | ||
----------------- ДОПОЛНИТЕЛЬНЫЕ ФУНКЦИИ ---------------------------------- | ----------------- ДОПОЛНИТЕЛЬНЫЕ ФУНКЦИИ ---------------------------------- | ||
+ | <!--T:44--> | ||
function bit(n) | function bit(n) | ||
return 2 ^ (n - 1) -- возвращает число - вес разряда номер n | return 2 ^ (n - 1) -- возвращает число - вес разряда номер n | ||
end | end | ||
+ | <!--T:45--> | ||
function hasbit(x, p) | function hasbit(x, p) | ||
return x % (p + p) >= p -- возвращает состояние бита p как true/false; if hasbit(value, bit(2)) then ... | return x % (p + p) >= p -- возвращает состояние бита p как true/false; if hasbit(value, bit(2)) then ... | ||
end | end | ||
+ | <!--T:46--> | ||
function setbit(x, p) | function setbit(x, p) | ||
return hasbit(x, p) and x or x + p -- установить бит № p в х Пример использования: х = setbit(х, bit(p)) | return hasbit(x, p) and x or x + p -- установить бит № p в х Пример использования: х = setbit(х, bit(p)) | ||
end | end | ||
+ | <!--T:47--> | ||
function clearbit(x, p) | function clearbit(x, p) | ||
return hasbit(x, p) and x - p or x -- тоже только снять бит | return hasbit(x, p) and x - p or x -- тоже только снять бит | ||
end | end | ||
+ | <!--T:48--> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Если различных операций над значениями много: не только сравнение, но и например проверка конкретного бита и т.п. то можно детали реализации спрятать в функцию, которая получит на вход табличку с типом операции (установлен ли конкретный бит, код ошибки, параметр в границах и т.п.) и входным значением и поставит или сбросит нужный бит. | Если различных операций над значениями много: не только сравнение, но и например проверка конкретного бита и т.п. то можно детали реализации спрятать в функцию, которая получит на вход табличку с типом операции (установлен ли конкретный бит, код ошибки, параметр в границах и т.п.) и входным значением и поставит или сбросит нужный бит. | ||
+ | <!--T:49--> | ||
<syntaxhighlight lang = lua> | <syntaxhighlight lang = lua> | ||
+ | <!--T:50--> | ||
for i,v in pairs(allAlerts) do | for i,v in pairs(allAlerts) do | ||
alertInput = GetReg(v.srcAlias) -- читаем регистр | alertInput = GetReg(v.srcAlias) -- читаем регистр |
Версия 17:14, 23 марта 2018
Содержание
Битовые операции
Удобные битовые операции
Можно определить несколько удобных битовых операций, помня о том что в lua биты нумеруются с 1. Ссылка взята отсюда, там же есть и другие полезные функции.
function bit(n)
return 2 ^ (n - 1) -- возвращает число - вес разряда номер n
end
function hasbit(x, p)
return x % (p + p) >= p -- возвращает состояние бита p как true/false; if hasbit(value, bit(2)) then ...
end
function setbit(x, p)
return hasbit(x, p) and x or x + p -- установить бит № p в х Пример использования: х = setbit(х, bit(p))
end
function clearbit(x, p)
return hasbit(x, p) and x - p or x -- тоже только снять бит
end
Преобразование битовой таблички в число
Данная функция может быть полезна для нестандартных преобразований, когда число хранится в специфичном формате и его необходимо обработать по частям, используя заданную позицию 1-го бита и длину поля значения.
function getNumberFromTab(tab,start,length) -- получить число из таблички
local result_str = "";
for i=start,(start+length-1) do
result_str = result_str..tostring(tab[i]);
end
return tonumber(result_str,2);
end -- getNumberFromTab
Преобразование числа в битовую табличку
В lua (в версии, используемой в WebHMI) нет встроенной операции получения строкового представления двоичного числа. Однако эта функция очень полезна в пользовательсиких протоколах и др. задачах, где требуется перераспределить или каким то образом обработать отдельные биты числа. Текст варианта такой функции:
function getBits(input_num,length) -- работает с заданной длиной
local tab = {}; -- пустая табличка для ответа
local max_i = length - 1;
local remainder = input_num; -- остаток порязрядного взешивания
for i=max_i,0,-1 do
if remainder - 2^i >= 0 then
table.insert(tab, "1") ;
remainder = remainder - 2^i;
else
table.insert(tab, "0") ;
end
end
return tab;
end -- getBits
Далее можно переставить нужные биты местами и т.п. и получить нужное число. Ниже приведен пример перестановки битов 31 и 23 битов (при нумерации битов с 0) в ответе счетчика расходомера ВЛР 2301/2304 производства Асвега-У
function main (userId)
local input_num = GetReg(3); -- прочитать регистр с числом
local bitTable = getBits(input_num,32); -- таблица для обработки результата
local tmp_bit = ""; -- вспомогательный бит
tmp_bit = bitTable[1];
bitTable[1] = bitTable[9]; -- 31 бит это 1 элемент так как таблица развернута слева-направо, номера элементов табл.в lua c 1
bitTable[9] = tmp_bit;
-- конкатенация готовой таблицы в строку и преобразование в число из строки двоичного представления
WriteReg(1, tonumber(table.concat(bitTable),2));
end
Обработка чисел с плавающей точкой двойной точности
Некоторые устройства могут хранить данные в формате с повышенной точностью double float. В WebHMI текущей версии поддерживаются только 32 битные регистры, поэтому чтобы обработать 64 битное число необходимо будет использовать скрипт, которые "сцепит" два регистра в исходное число, а затем преобразует и запишет в обратно в float. Регистры должны быть типа double uint. Для "сцепки" чисел можно использовать описанную выше функцию getBits чтобы получить 2 таблицы, а затем дополнить первую таблицу битами из второй используя table.insert. В этом примере в качестве проверочного числа для простоты используется константа.
--------------------------------------
local test_var = 0xC1D312D000000000;
local NaN = tonumber("11111111111111111111111111111111",2);
--------------------------------------
function main (userId)
-- получить результирующую табличку "0" "1"
local result_tab = getBits(test_var,64);
WriteReg(11,table.concat(result_tab)); -- отладочная печать в регстр - строку
local result_num = 0.0; -- для хранения результата
local sign,exp,mantissa = 0,0,0;
local fraction_table = {}; -- табл. для дробной части
-- определить знак
if result_tab[1] == "1" then
sign = -1;
else
sign = 1;
end
-- экспоненту
exp = getNumberFromTab(result_tab,2,11);
DEBUG("exp = "..tostring(exp)); -- отл. печать
-- мантиссу
for i=13,64 do
table.insert(fraction_table,result_tab[i]);
end
-- посчитать мантиссу по-разрядно !!!
for j=1,52 do
if fraction_table[j]=="1" then
mantissa = mantissa +(2^(-1*j));
end
end
mantissa = mantissa +1;
DEBUG("m = "..tostring(mantissa)); -- отл. печать
result_num = sign*(2^(exp - 1023))*mantissa;
-- Обработка исключений
if exp == 0 then -- subnormals
result_num = sign*(2^(-1022))*(mantissa-1);
end
if exp == 0x7ff then -- nan
result_num = NaN;
end
-- Вывод результата в регистр типа float
WriteReg(10, result_num);
end -- main
Формирование общего регистра аварий по разным условиям
В WebHMI есть механизм аварий. Т.е. по состоянию бита в регистре можно автоматически генерировать записи в журнале о моменте возникновения, снятия аварии, квитировании ее оператором.
Однако в некоторых случаях использовать данный механизм непосредственно, как есть, может не совсем быть удобно. Например - аварийным считается определенный бит или их комбинация, разные коды ошибок (и их надо отличать друг от друга), значение больше или меньше порога и т.д. Если регистр имеет уже настроенные состояния для аварийной ситуации, используемое для отображения, то его нужно просто продублировать, выставив бит в общем аварийном регистре. Также может потребоваться введение задержки на срабатывание аварии, так как значение может иметь "дребезг" который надо фильтровать, прежде чем генерировать аварию в журнале. Кроме этого удобнее, когда все аварии описаны в одном месте, а не разбросаны по сотням регистров. Т.е. рациональнее использовать один или несколько несколько 32-битных регистров для описания всех возможных аварий, и скрипт в котором эти аварии будут записываться в этот регистр по разным условиям. Ниже приведен пример такого скрипта:
Допустим, есть некая функциональная единица, например приточная вентиляционная установка, в которой есть некий общий признак аварии, есть несколько регистров с кодами текущих ошибок от частотных преобразователей и ситуация, когда один из регистров (влажность, СО2 и др.) вышел за допустимый диапазон, что является также аварийной ситуацией.
Тогда скрипт, который обработает все эти ситуации и сформирует нужные флаги на своих местах может выглядеть так:
allAlerts = { -- регистр бит - код ошибки тип операции
{srcAlias = "pv1Status", bits = {[1] = 1}, "bit9"},
{srcAlias = "vfdStatus_1", bits = {[2] = 10, [3] = 20, [4] = 30, [5] = 40}, "=="},
{srcAlias = "vfdStatus_2", bits = {[6] = 10, [7] = 20, [8] = 30, [9] = 40}, "=="},
{srcAlias = "pv1ZoneHumidity", bits = {[10] = 90}, ">="}
}
intAlertReg = "alertsReg" -- ОБЩИЙ РЕГИСТР АВАРИЙ
function main (userId)
local alertInput, alertOut = 0,0 -- временные переменные для чтения аварий и формирования результата
local digit = 0 -- номер бита в исходном регистре, указывающий на аварию..
--[[
Если назвать единообразно все параметры,
из которых надо формировать аварии и сложить их в одну структуру,
тогда можно использовать только один цикл for, например так:
--]]
for i,v in pairs(allAlerts) do
alertInput = GetReg(v.srcAlias) -- читаем регистр
for j,k in pairs(v.bits) do -- выполнится по числу элементов в под-табличке bits
-- проверяем тип операции - точное совпадение или другое условие
if (v[3] == "==") then
-- проверяем регистр на один из кодов ошибок
if (alertInput == k) then
alertOut = setbit(alertOut, j)
else
alertOut = clearbit(alertOut, j)
end
-- проверяем определенный бит
elseif (string.find(v[3], "bit%d+") ~= nil) then -- %d+ паттерн любая последовательность цифр
_,_,digit = tonumber(string.find(v[3], "bit(%d+)")) -- выделить из паттерна цифру и преобразовать в число
if hasbit(alertInput, bit(digit)) then -- если заданный бит установлен во входном регистре
alertOut = setbit(alertOut, j)
else
alertOut = clearbit(alertOut, j)
end
else
--- другие операции
end
end -- for bits inside
end -- for allAlerts
-- теперь просто записать то что получилось в общий регистр аварий
WriteReg(intAlertReg, alertOut)
end -- main
----------------- ДОПОЛНИТЕЛЬНЫЕ ФУНКЦИИ ----------------------------------
function bit(n)
return 2 ^ (n - 1) -- возвращает число - вес разряда номер n
end
function hasbit(x, p)
return x % (p + p) >= p -- возвращает состояние бита p как true/false; if hasbit(value, bit(2)) then ...
end
function setbit(x, p)
return hasbit(x, p) and x or x + p -- установить бит № p в х Пример использования: х = setbit(х, bit(p))
end
function clearbit(x, p)
return hasbit(x, p) and x - p or x -- тоже только снять бит
end
Если различных операций над значениями много: не только сравнение, но и например проверка конкретного бита и т.п. то можно детали реализации спрятать в функцию, которая получит на вход табличку с типом операции (установлен ли конкретный бит, код ошибки, параметр в границах и т.п.) и входным значением и поставит или сбросит нужный бит.
for i,v in pairs(allAlerts) do
alertInput = GetReg(v.srcAlias) -- читаем регистр
alertOut = MyGetAlerts(alertInput, alertOut, v) -- вызываем функцию, которая посмотрит что надо сделать по полю v[3], т.е. allAlerts[3]
end -- for