OberonCore
https://forum.oberoncore.ru/

Двоичная математика
https://forum.oberoncore.ru/viewtopic.php?f=27&t=884
Страница 1 из 1

Автор:  hothing [ Вторник, 19 Февраль, 2008 20:22 ]
Заголовок сообщения:  Двоичная математика

Математики, просьба помочь вот с такой задачей:
необходимо реализовать следующую функцию
x[2*i+1] = NOT x[2*i],
где x[] - бит в слове x
i - номер 2-битной группы
Или словами: необходимо инвертировать каждый четный бит, и записать результат в нечетный с большим индексом.
Основное условие: использовать как можно меньше операций над словами.

Спасибо.

Автор:  Илья Ермаков [ Вторник, 19 Февраль, 2008 21:30 ]
Заголовок сообщения:  Re: Двоичная математика

Если я верно понял, то:
x, res: INTEGER;
even_bits: SET;
even_bits := BITS(x) * {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
res := ORD(even_bits + BITS(ASH(ORD(-even_bits), 1)));

Реальных операций только три: *, + и - (побитовый and, or и not соответственно).
Остальное - преобразования этапа трансляции.

Автор:  hothing [ Среда, 20 Февраль, 2008 10:03 ]
Заголовок сообщения:  Re: Двоичная математика

Илья, спасибо.

Уже решил задачку. Хороший сон положительно сказывается на сообразительности :)
НЕ все варианты проверил, но по идее должно работать:

(* псевдокод *)
CONST
m1 = 2#10101010 (* маска групп*)
m2 = ~m1 (* инвресная маска *)
VAR
x: BYTE;
y: BYTE;
BEGIN
y := ASH(x); (*сдвигаем на 1 разряд влево*)
y := ~(y AND m1) AND (y OR m1); (* y := y XOR m1 *)
y := y OR m2;
END.

Мне надо на ассемблере сделать, для довольно экзотического ПЛК, в котором каждая команда от 2 до 5 байт занимает, при работе с битовыми полями. А памяти, как всегда, мало. :) Для 32-битных слов этот код занимает около 30 байт. А если делать красиво по-битово, то хапает сразу около 300 байт.

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