Разобрался с типом SET, я работал с set в Питоне и долго не мог понять этот загадочный SET в ББ, который жестко предопределен по длине и содержимому. На понимание меня натолкнули две вещи
(конечно, помимо обсуждения выше).
Дак вот, первая зацепка - это строчка
Цитата:
SET позволяет писать драйвера которые не зависят от порядка битов машины
не помню, где на это натолкнулся. Я понял для чего используют SET в КП - для битовых операций!
Но это я не понимал, пока не задумался над вопросом "почему этот SET содержит 32 элемента?" и тут я понял, что SET это ТУПО битовое представление INTEGER. Все встало на свои места, и этот загадочный алгоритм команды BITS(), который я безуспешно пытался разгадать больше часа
В итоге, для таких чайников как я предлагаю демку, ее возможно дополнить, но для моей проблемы это само-то!
Код:
MODULE DiaSet;
IMPORT StdLog;
PROCEDURE BinLog* (int: INTEGER);
VAR s: SET; i: INTEGER; str: ARRAY 33 OF CHAR;
BEGIN
s := BITS(int);
str := '';
StdLog.Int(int); StdLog.Set(s); StdLog.Ln;
FOR i := 31 TO 0 BY - 1 DO
IF i IN s THEN
str := str$ + '1'
ELSE
str := str$ + '0'
END
END;
str[32] := 0X;
StdLog.String(str); StdLog.Ln
END BinLog;
PROCEDURE Application* (int, from, to: INTEGER): INTEGER;
VAR s: SET; i: INTEGER; str: ARRAY 33 OF CHAR;
BEGIN
s := BITS(int);
s := s * {from .. to};
RETURN ASH(ORD(s), - from)
END Application;
PROCEDURE DemoSet*;
VAR s: SET; i: INTEGER;
BEGIN
StdLog.Ln;
StdLog.String("Числа от 0 до 10"); StdLog.Ln;
FOR i := 0 TO 10 DO
BinLog(i)
END;
StdLog.Ln;
StdLog.String("Исходное число"); StdLog.Ln;
BinLog(143);
StdLog.Ln;
StdLog.String("Пересечение с {0 .. 3} = ...000011111");
StdLog.Ln;
s := BITS(143) * {0 .. 3};
BinLog(ORD(s));
StdLog.Ln;
StdLog.String("Пересечение с {4 .. 7} = ...11110000");
StdLog.Ln;
s := BITS(143) * {4 .. 7};
BinLog(ORD(s));
StdLog.Ln;
StdLog.String("Демонстрация операции ASH от -2 до 5 для 111 (7)");
StdLog.Ln;
FOR i := - 2 TO 5 DO
BinLog(ASH(7, i))
END;
StdLog.Ln;
StdLog.String("Демонстрация применения SET для дешифровки 1000xxxxb = 8Xh, X = ?");
StdLog.Ln;
StdLog.String("Исходное число 1000xxxxb"); StdLog.Ln;
BinLog(135);
StdLog.String("Результат xxxx"); StdLog.Ln;
BinLog(Application(135, 0, 3));
StdLog.Ln;
StdLog.String("Демонстрация применения SET для дешифровки YYYYxxxYb");
StdLog.Ln;
StdLog.String("Исходное число 1000xxx0b"); StdLog.Ln;
BinLog(135);
StdLog.String("Результат xxx"); StdLog.Ln;
BinLog(Application(135, 1, 3));
END DemoSet;
END DiaSet.
^Q DiaSet.DemoSet
Это далеко не все для чего нужно SET, часто в КП этот тип используется для
передачи различных параметров.
К SET применяются
EXCL(v, x) v: SET; x: целый тип, v := v - {x}
0 <= x <= MAX(SET)
INCL(v, x) v: SET; x: целый тип, v := v + {x}
0 <= x <= MAX(SET)
ORD(x) = (SUM i: i IN x: 2^i)
Из сообщения о языке компонентный паскаль
8.2.3 Операции над множествами
+ объединение
- разность (x - y = x * (-y))
* пересечение
/ симметричная разность (x / y = (x-y) + (y-x))
Операции над множествами применимы к операндам типа SET и дают результат типа SET. Одноместный минус обозначает дополнение множества x, т.е. -x обозначает множество целых от 0 до MAX(SET), которые не являются элементами множества x. Операции над множествами не являются ассоциативными ((a+b)-c # a+(b-c)).
Конструктор множества определяет значение множества перечислением его элементов между фигурными скобками. Элементы должны быть целыми в диапазоне 0..MAX(SET). Диапазон a..b обозначает все целые i такие, что i >= a и i <= b.