OberonCore https://forum.oberoncore.ru/ |
|
Как добыть биты из байтов? (или загадочный тип данных SET) https://forum.oberoncore.ru/viewtopic.php?f=35&t=3287 |
Страница 1 из 2 |
Автор: | Иван Денисов [ Воскресенье, 27 Февраль, 2011 09:18 ] |
Заголовок сообщения: | Как добыть биты из байтов? (или загадочный тип данных SET) |
Принимаю байты от устройства, а в документации написано. Формат ответа: 1000xxxxb = 8Xh и X код ответа! Как это чудо извлечь? Научился BYTE в SET конвертировать, но это пока ничего не дало ![]() |
Автор: | Александр Ильин [ Воскресенье, 27 Февраль, 2011 09:47 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
divan писал(а): Принимаю байты от устройства, а в документации написано. Mask = 00010000b;Формат ответа: 1000xxxxb = 8Xh и X код ответа! Как это чудо извлечь? Научился BYTE в SET конвертировать, но это пока ничего не дало :( Result := Result MOD Mask; Если маска содержит одну единичку, то результат MOD = битам справа от единички. X MOD 00010000b = X & 00001111b Результат DIV - наоборот - все биты слева от единички, включая бит с единичкой, только сдвинутое вправо: X DIV 00010000b = X & 11110000b >> 4 |
Автор: | Евгений Темиргалеев [ Воскресенье, 27 Февраль, 2011 10:25 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Возможно для понимания будет полезно поглядеть на объяснение Александра из 10-й системы. result = 12345678; mask = 10^n, n = 3 mask = 1000; result MOD mask = 678 --- обнуляются все старшие цифры, начиная с позиции n result DIV mask = 12345 --- сдвиг на n позиций вправо (что "выехало за пределы целого" --- отбразываем) И потом вспомнить, что наши компы построены на базе 2-й системы, в которой эти оптимизации применимы при mask = 2^n. Чем и пользуются писатели компиляторов (см. Построение компиляторов, 16.2 Простые оптимизации). Результат оптимизации м.б. записан на КП напрямую: result MOD 2^k = ORD(BITS(result) * {0..k-1}) result DIV 2^k = ASH(result, -k) |
Автор: | Иван Денисов [ Воскресенье, 27 Февраль, 2011 10:32 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Спасибо, начал понимать. А как заставить ББ понять вот это 00010000b ? Он ругается на такое. Неужели придется манипулировать 8-значными числами типа INTEGER, 00010000, например. |
Автор: | Info21 [ Воскресенье, 27 Февраль, 2011 10:51 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
divan писал(а): А как заставить ББ понять вот это 00010000b ? Кажется, понял.Он ругается на такое. Неужели придется манипулировать 8-значными числами типа INTEGER, 00010000, например. b -- binary, h -- hexadeciaml. А поступает байт. Получаете свой 1000xxxxb от железа в b: BYTE (Вы, вроде, это сумели). Перегоняете в n: INTEGER простым присваиванием n := b. Перегоняете в x: SET с помощью x := BITS(n). Делаете y := x * {0 .. 3} -- это оставит только нужные 4 бита (пересечение множеств). Потом ORD(y) будет Вашим кодом. Вроде, так. |
Автор: | Иван Денисов [ Воскресенье, 27 Февраль, 2011 11:04 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Отлично, сейчас попробую ![]() |
Автор: | Info21 [ Воскресенье, 27 Февраль, 2011 11:09 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
divan писал(а): Отлично, сейчас попробую Не забывайте про ASH, который позволит "придвинуть" выделенную тройку битов в нужную позицию (после преобразования к INTEGER).
![]() |
Автор: | Евгений Темиргалеев [ Воскресенье, 27 Февраль, 2011 12:45 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
divan писал(а): А как заставить ББ понять вот это 00010000b ? КП допускает использование 10-х и 16-х констант. Двоичные просто выражать через 16-е (каждые 4 бита = одна 16-я цифра).Он ругается на такое. Неужели придется манипулировать 8-значными числами типа INTEGER, 00010000, например. 00010000b = 10H 10100011b = 0A3H Двоичную вида 2^k можно получить как ASH(1, k): 00010000b = ASH(1, 4) |
Автор: | Info21 [ Воскресенье, 27 Февраль, 2011 13:21 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Поправил: должно быть {0 .. 3}, а не {3 .. 0}. |
Автор: | Сергей Губанов [ Воскресенье, 27 Февраль, 2011 22:23 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
divan писал(а): Принимаю байты от устройства Ещё биты могут быть в другом порядке. То есть, в документации будет речь, например, о первом бите, а в интеловской машине это будет шестой. Так как в документации обычно пишут номера битов в том порядке в каком они передаются, а передаются они обычно как big-endian. В RFC для RTP например такая засада с порядком битов есть.
|
Автор: | Alexey Veselovsky [ Понедельник, 28 Февраль, 2011 00:26 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
По умолчанию обычно network order у битиков. ntohl htonl и их собратья в помощь ( не знаю есть их аналог в ББ или нет). В RTP это не засада, это как раз нормально. Вот в rtmp там засада, когда оказывается, что часть полей ВНЕЗАПНО на самом деле едут не в network order'e. |
Автор: | Евгений Темиргалеев [ Понедельник, 28 Февраль, 2011 09:52 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Alexey Veselovsky писал(а): ntohl htonl и их собратья в помощь ( не знаю есть их аналог в ББ или нет) Эта тема для того, чтобы вопросы по ББ задавать. Либо на них отвечать. Стандартная библиотека Си --- оффтоп.
|
Автор: | Info21 [ Понедельник, 28 Февраль, 2011 10:24 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Сергей Губанов писал(а): divan писал(а): Принимаю байты от устройства Ещё биты могут быть в другом порядке.Но это проблема, если вообще программу ни разу не тестировать. Аспирант-биофизик, живущий среди экспериментального оборудования, должен, по-моему, догадаться проверить, что к нему приходит по шнурку, простой распечаткой получающегося SET'а ![]() В данном случае, надеюсь, с самого начала проблемы с этим пунктом не было. Ждем рапорта об успехе проектика ![]() |
Автор: | Иван Денисов [ Понедельник, 28 Февраль, 2011 17:37 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Разобрался с типом 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. |
Автор: | Info21 [ Понедельник, 28 Февраль, 2011 21:26 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
divan писал(а): Разобрался с типом SET, я работал с set в Питоне и долго не мог понять ... Вот он вред от ерунды всякой, только голову замусоривать.
|
Автор: | Info21 [ Понедельник, 28 Февраль, 2011 21:46 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
divan писал(а): На понимание меня натолкнули две вещи Интересный пунктик. Действительно, не так просто узнать о том, что SET -- для работы с битами. У меня не отложилось, что это проблема, иначе добавил бы комментарий в Сообщение.Но в документе Что нового в Компонентном Паскале, в разделе Фиксированные диапазоны значений типов, есть таблица, а в ней строчка SET 4 byte набор бит Вероятно, люди, которые тут тусуются, читали этот документ "в первых рядах" и сразу усекли это дело. Интересно, коллеги, кто помнит, как возникло понимание типа SET? Я за 15 лет уже забыл свой опыт. |
Автор: | Валерий Лаптев [ Вторник, 01 Март, 2011 07:03 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Info21 писал(а): divan писал(а): Разобрался с типом SET, я работал с set в Питоне и долго не мог понять ... Вот он вред от ерунды всякой, только голову замусоривать.Не... Эт не ерунда.Студень, можно сказать, с младых ногтнй заучивает в математике, что множество - это набор однотипных элементов... В языках программирования (в том же паскале) - так и есть, обычно. И вдруг, в КП SET имеет другой смысл. Я-то старый программер, просек быстро. Тем более, что с битами еще на Минске-22 пришлось иметь дело... А неопытному видите, сколько думать пришлось - вплоть до озарения... Это не есть good. Поэтому нужна какая-то книжка типа "КП для сионистов"... Я лабы буду в ББ "контентить" по вашему примеру, буду на данный момент внимание обращать. |
Автор: | Евгений Темиргалеев [ Вторник, 01 Март, 2011 09:32 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Валерий Лаптев писал(а): Info21 писал(а): divan писал(а): Разобрался с типом SET, я работал с set в Питоне и долго не мог понять ... Вот он вред от ерунды всякой, только голову замусоривать.Отличие реализации в Обероне: используется массив битов (=массив значений хар-й ф-и), размерность которого ограничена словом машины. Вместо фикс. массива битов большего размера или динамического, поддержку которого надо как-то вделывать в компилятор. Отказ от поддержки этой искусственной сущности компилятором в пользу библиотек есть следование "keep it simple as possible, but not simple". |
Автор: | Евгений Темиргалеев [ Вторник, 01 Март, 2011 09:38 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Info21 писал(а): Интересно, коллеги, кто помнит, как возникло понимание типа SET? http://www.inf.ethz.ch/personal/wirth/A ... n/SETs.pdf
|
Автор: | Иван Денисов [ Вторник, 01 Март, 2011 10:29 ] |
Заголовок сообщения: | Re: Как добыть биты из байтов? |
Евгений Темиргалеев писал(а): Info21 писал(а): Интересно, коллеги, кто помнит, как возникло понимание типа SET? http://www.inf.ethz.ch/personal/wirth/A ... n/SETs.pdfВот уж точно "A neglected data type" - "заброшенный тип данных". Да эта статья бы сразу все прояснила, даже если английского не знать, то вот эта табличка Цитата: 0 00000000 {} сразу подталкивает к пониманию.
1 00000001 {0} 5 00000101 {0, 2} 55H 01010101 {0, 2, 4, 6} |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |