OberonCore
https://forum.oberoncore.ru/

Побитовые операции
https://forum.oberoncore.ru/viewtopic.php?f=81&t=185
Страница 1 из 2

Автор:  Grabli [ Пятница, 28 Апрель, 2006 08:18 ]
Заголовок сообщения:  Побитовые операции

Почему:

Byte:=240;
IF Byte & 8 THEN DoSomeThing();

Не хочет работать.

Автор:  Илья Ермаков [ Пятница, 28 Апрель, 2006 12:00 ]
Заголовок сообщения: 

Так побитовых операций в Оберонах нет применительно к INTEGER. INTEGER надо истрактовать как SET (он в КП всегда только 32-битный {0..31}), затем провести операции над множествами, потом вернуть в INTEGER. Например, and - это пересечение множеств, *:
ORD(BITS(a)*BITS(b))
or - сложение множеств, +:
ORD(BITS(a) + BITS(b))
xor - симметрическая разность, /:
ORD(BITS(a) / BITS(b))
not - дополнение множества, -:
ORD(-BITS(a))
Никаких накладных расходов эти операции не вносят, это те же побитовые операции в завуалированной форме.

Автор:  PGR [ Четверг, 05 Апрель, 2007 02:03 ]
Заголовок сообщения: 

Получается, простая операция сброса одного бита в байте, которая на Си записывается

Код:
byte = byte & ~(1<<(7-bit_pos))


превращается в

Код:
byte := SHORT(SHORT(ORD(BITS(byte) * (-BITS(ASH(1, 7-bit_pos))))))

Автор:  Trurl [ Четверг, 05 Апрель, 2007 08:40 ]
Заголовок сообщения: 

Немного проще
Код:
byte := SHORT(SHORT(ORD(BITS(byte) - {7-bit_pos})))


Но, вообще говоря, незачем заводить переменную типа BYTE, чтобы сбрасывать в ней биты.

Автор:  Евгений Темиргалеев [ Пятница, 06 Апрель, 2007 11:49 ]
Заголовок сообщения: 

Trurl писал(а):
Немного проще
Код:
byte := SHORT(SHORT(ORD(BITS(byte) - {7-bit_pos})))


Но, вообще говоря, незачем заводить переменную типа BYTE, чтобы сбрасывать в ней биты.[/code]
Вот вот. В КП это делается гораздо проще.
Код:
VAR a: SET;...
a := a - {bit_pos};

Автор:  PGR [ Пятница, 06 Апрель, 2007 18:16 ]
Заголовок сообщения: 

Евгений Темиргалеев писал(а):
Вот вот. В КП это делается гораздо проще.
Код:
VAR a: SET;...
a := a - {bit_pos};


Не так все просто...
Если потом эти множества записать в файл (потоком байтов), то где гарантия что 4 байта SET будут записаны в нужном порядке (big-endian или little-endian)?

Автор:  Александр Ильин [ Пятница, 06 Апрель, 2007 20:23 ]
Заголовок сообщения: 

PGR писал(а):
Не так все просто...
Если потом эти множества записать в файл (потоком байтов), то где гарантия что 4 байта SET будут записаны в нужном порядке (big-endian или little-endian)?

Есть такая константа: Kernel.littleEndian* = True;
Активно используется модулем Stores при записи и чтении. См., например, Stores.Reader.ReadSet или Stores.Writer.WriteSet.
Так что если будете пользоваться стандартными средствами, проблем не будет. Если будете изобретать свое колесо, то просто учитывайте значение константы.

Автор:  ilovb [ Среда, 14 Октябрь, 2009 18:47 ]
Заголовок сообщения:  Побитовый AND

Прикреплена тема "Побитовый AND" из viewforum.php?f=2

Не нашел в среде. Сляпал свой. Может надо кому...

MODULE My;
IMPORT StdLog, SYSTEM;

PROCEDURE [code] BitAnd*(a: INTEGER; b: INTEGER) :INTEGER
05BH, 021H, 0D8H;


PROCEDURE Do*;
VAR i, j: INTEGER;
BEGIN
FOR j:=0 TO 100 DO
i:=BitAnd(j,5);
StdLog.Int(i);
END;
END Do;
END My.
My.Do

Автор:  Илья Ермаков [ Среда, 14 Октябрь, 2009 18:53 ]
Заголовок сообщения:  Re: Побитовый AND

Побитовые операции делаются через тип SET и преобразования BITS(int_val) и ORD(set_val).

См.:
viewtopic.php?f=29&t=185

(разумеется, никаких накладных расходов это не добавляет; операции чисто компиляторные).

Автор:  ilovb [ Среда, 14 Октябрь, 2009 20:50 ]
Заголовок сообщения:  Re: Побитовый AND

Илья Ермаков писал(а):
...
(разумеется, никаких накладных расходов это не добавляет; операции чисто компиляторные).

Действительно...
Скомпоновал вот это в DLL:
MODULE FDLL;
IMPORT SYSTEM;

PROCEDURE [code] Bit(a: INTEGER; b: INTEGER) :INTEGER
05BH, 021H, 0D8H;

PROCEDURE BitAnd1*(a: INTEGER; b: INTEGER) :INTEGER;
BEGIN RETURN Bit(a,b) END BitAnd1;

PROCEDURE BitAnd2*(a: INTEGER; b: INTEGER) :INTEGER;
BEGIN RETURN ORD(BITS(a)*BITS(b)) END BitAnd2;

END FDLL.
:!: DevLinker.LinkDll
FDLL2.dll := FDLL# ~


Disassembler выдал такое:
Exported fn(): BitAnd1 - Ord:0001h
:00401035 55 push ebp
:00401036 8BEC mov ebp, esp
:00401038 57 push edi
:00401039 56 push esi
:0040103A FF750C push [ebp+0C]
:0040103D 8B4508 mov eax, dword ptr [ebp+08]
:00401040 5B pop ebx
:00401041 21D8 and eax, ebx
:00401043 8D65F8 lea esp, dword ptr [ebp-08]
:00401046 5E pop esi
:00401047 5F pop edi
:00401048 5D pop ebp
:00401049 C20800 ret 0008

Exported fn(): BitAnd2 - Ord:0002h
:0040104C 55 push ebp
:0040104D 8BEC mov ebp, esp
:0040104F 57 push edi
:00401050 56 push esi
:00401051 8B4508 mov eax, dword ptr [ebp+08]
:00401054 23450C and eax, dword ptr [ebp+0C]
:00401057 8D65F8 lea esp, dword ptr [ebp-08]
:0040105A 5E pop esi
:0040105B 5F pop edi
:0040105C 5D pop ebp
:0040105D C20800 ret 0008

Разницы практически никакой :)
Кстати процедура Bit в DLL не компонуется почему-то. Нужно в обычную упаковывать...

Автор:  Илья Ермаков [ Среда, 14 Октябрь, 2009 20:52 ]
Заголовок сообщения:  Re: Побитовый AND

Вы не забывайте, что вы декомпилируете код для процедуры.

И там куча обвязки по сохранению регистров, и т.п. Всё как положено.

Битовые операции пишутся по месту (без введения процедур).
Вот как раз и код: :00401054 23450C and eax, dword ptr [ebp+0C]
Просто and. Остальное - доставка к этому and параметров неизвестно зачем введённой процедуры :)

Автор:  Сергей Губанов [ Четверг, 15 Октябрь, 2009 10:04 ]
Заголовок сообщения:  Re:

Цитата:
big-endian или little-endian
Кстати, проблема, как мне кажется, в значительной степени надуманная: всё равно не существует big-endian реализации Блэкбокса, так чего воду мутить? Надо просто в спецификации сказать, что всё всегда сериализуется в little-endian, а те несчастные которые работают на big-endian машинах вот пусть сами и парятся при десериализации, а мы парится не будем :D .

Автор:  Trurl [ Четверг, 15 Октябрь, 2009 10:15 ]
Заголовок сообщения:  Re: Re:

Сергей Губанов писал(а):
всё равно не существует big-endian реализации Блэкбокса, так чего воду мутить? .

Смотря в каком смысле понимать "существует".

Автор:  Сергей Губанов [ Четверг, 15 Октябрь, 2009 10:21 ]
Заголовок сообщения:  Re: Побитовые операции

И в каком смысле?

Автор:  Илья Ермаков [ Четверг, 15 Октябрь, 2009 11:07 ]
Заголовок сообщения:  Re: Побитовые операции

Для PowerPC ведь валяется... Версия 1.3.

Автор:  Роман М. [ Понедельник, 16 Ноябрь, 2009 22:47 ]
Заголовок сообщения:  Побитовые операции над числами

Присоединено к уже существующей теме.

За неимением функций побитовой работы над целами числами решил написать такие процедуры.
Насколько я понял из документации, побитовые операции делаются через множества.

При такой реализации BB сообщает о 2 ошибках.
Код:
MODULE bitwise_test;

PROCEDURE BitAnd (a, b: INTEGER): INTEGER;
VAR
   R: SET;
   I: INTEGER;
BEGIN
   R := {a} * {b};
   I := INTEGER(R); (* здесь *)
   RETURN I;
END Bitand; (* и здесь *)

END bitwise_test.


Это понимать как неверное приведение одного типа к другому?

Автор:  Валерий Лаптев [ Понедельник, 16 Ноябрь, 2009 22:52 ]
Заголовок сообщения:  Re: Побитовые операции над числами

Для приведения целогоь к множеству и обратно надо встроенные функции КП использовать. Они прописаны в сообщении о языке - посмотрите в справочнике ББ.

Автор:  QWERTYProgrammer [ Понедельник, 16 Ноябрь, 2009 22:53 ]
Заголовок сообщения:  Re: Побитовые операции над числами

Я делал
Код:
ORD(BITS(a)*BITS(b))

Автор:  Роман М. [ Понедельник, 16 Ноябрь, 2009 22:54 ]
Заголовок сообщения:  Re: Побитовые операции над числами

Какую страницу, не подскажете? (англ. версия)

Автор:  Валерий Лаптев [ Понедельник, 16 Ноябрь, 2009 22:56 ]
Заголовок сообщения:  Re: Побитовые операции над числами

В самом конце документа встроенные функции.

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/