Автор Тема: Отзеркалить биты в байте  (Прочитано 4725 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1770
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Нужен очень простой и быстрый алгоритм - отзеркалить биты в байте - так, чобы самый старший стал малдшим и так далее. В интернете примеры все какие то громоздкие, неужели нет простого и красивого решения?

Например здесь - http://forum.sources.ru/index.php?showtopic=49181
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

pumpkin

  • Модератор Раздела
  • Профи
  • *
  • Сообщений: 240
  • Карма: 2
  • Пол: Мужской
  • Это Я :-)
    • Просмотр профиля
Re: Отзеркалить биты в байте
« Ответ #1 : 18 Январь 2013, 20:01:51 »
Самый быстрый алгоритм - готовый массив уже реверснутых байт. Занимает 256 байт, но работает чертовски быстро:
Y = Rev[X]
А так? вот вполне компактный и код, и довольно быстрый (57 команд на один байт). Синтаксис Паскаля:
function Rev(B:Byte):Byte;
var
  i: Integer;
begin
  Result := 0;
  for i := 0 to 7 do
    Result := Result or (((B and (1 shl i)) shr i) shl (7-i));
end;

// ---------------------------
Y := Rev(X);

На баскоме:
$regfile = "m48def.dat"
$crystal = 4000000
$baud = 19200

Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

Dim X As Byte
Dim Y As Byte
Dim I As Byte
Dim Ix As Byte
Dim K As Byte


X = 77                                                      \'будет 178
Gosub Rev
Print Y

End

Rev:
Y = 0
For I = 0 To 7
  K = 1
  Shift K , Left , I
  K = K And X
  Shift K , Right , I
  Ix = 7 - I
  Shift K , Left , Ix
  Y = Y Or K
Next I
Return
« Последнее редактирование: 18 Январь 2013, 23:04:29 от pumpkin »

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1770
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Отзеркалить биты в байте
« Ответ #2 : 22 Январь 2013, 13:34:56 »
176 байт, неплохо. У меня идея появилась пихать биты в каким либо образом в стек, а потом забирать отуда. Можно в цикле, можно напрямую. Типа такого примера - (он нерабочий).

Цитировать
Mirror:
push r31
For J = 0 To 7
Nm = A_week.j
ldi  r31,{Nm}
push  r31
Next

For J = 0 To 7
pop r31
sts {Nm} ,r31
A_week.j = Nm
Next
pop r31
Return


Он занимает 162 байта, и его надо написать польностью на асме, проблема как из регистра с переменной выщелкнуть нужный бит в младший бит следующего регистра, чтобы сохранить в  стек, и сделать обратную процедуру. Иногда мне кажется что работа с битами - черезмерные наклодные расходы, проще сделать восмибайтный массив и работать с ним. 
« Последнее редактирование: 22 Январь 2013, 13:36:02 от admin »
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1770
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Отзеркалить биты в байте
« Ответ #3 : 22 Январь 2013, 14:26:25 »
Да, попробовал.. Действительно, работа с байтами куда короче. Массив из 8 байт работает быстрее и код короче получился. 125 байт.




Цитировать

Dim N As Byte
Dim K As Byte
Dim Cik As Byte
Dim Weekly(8) As Byte

Mirror:
Cik = 8
For J = 1 To 4
K = Weekly(j)
Weekly(j) = Weekly(cik)
Weekly(cik) = K
Decr Cik
Next
Return


Просто была идея использовать один байт для хранения дней недели когда срабатывать будильнику и собственно включен ли будильник, там он очень красиво разворачивался одной строкой на дисплей командой

Stroka = Bin(a_week)
Lcd Stroka

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

pumpkin

  • Модератор Раздела
  • Профи
  • *
  • Сообщений: 240
  • Карма: 2
  • Пол: Мужской
  • Это Я :-)
    • Просмотр профиля
Re: Отзеркалить биты в байте
« Ответ #4 : 22 Январь 2013, 20:00:43 »
У процессора нет команд для работы с конкретными битами. Надо самому выковыривать нужный бит, сдвигами и логическими опеациями.
Поэтому, если необходимости нет, лучше оперировать байтами, словами и т.д. И код будет понятнее, и потом его модифицировать будет проще.

Еще минус 10 байт  :) :
Mirror:
For I = 1 To 4
  Cik = 9 - I
  Swap Weekly(i) , Weekly(cik)
Next I
Return

Форум проекта "Минилаб-Мастер"

Re: Отзеркалить биты в байте
« Ответ #4 : 22 Январь 2013, 20:00:43 »

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1770
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Отзеркалить биты в байте
« Ответ #5 : 23 Январь 2013, 00:55:43 »
 :) Чувствуется программистская смекалка  :)
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Форум проекта "Минилаб-Мастер"

Re: Отзеркалить биты в байте
« Ответ #5 : 23 Январь 2013, 00:55:43 »