Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Нужно зеркально отобразить байт


Автор: Serenum 22.7.2004, 08:56
Дело в следующем, данные из последовательного порта записываются в память наоборот слева направо. Нужно написать программу, или может функция есть специальная, чтобы перевести число в нормальный вид. Помогите, я на С только начинаю... withstupid.gif

Автор: chipset 22.7.2004, 10:22
Делай маски в шестнацетиричном формате затем побитовой функцией & разделяй на биты и | собирай..
Может кто знает более правильный и красивый способ..

Автор: maxim1000 22.7.2004, 10:37
Код
unsigned char mirror(unsigned char x)
{
 unsigned char result=0;
 int c;

 for(c=0;c<8;c++)
 {
   result<<=1;
   if(x&1)
     result++;
   x>>=1;
 }
}

только я не проверял smile.gif

Автор: Alex101 22.7.2004, 11:39
Код
unsigned char mirror(unsigned char x)
{
unsigned char result=0;

for(int i=0;i<4;i++)
result+=(((x<<i)&1)>>(7-i)+(((x<<(7-i))&1)>>i)

return result;
}

Проверить не на чем.
Не уверен в скобках, но работать должно.

Автор: Guest 22.7.2004, 11:49
chipset
maxim1000

Ребят, можете поподробнее объяснить, что вы предлагаете. Т. е, извлечено число из порта, присвоено переменной , и дальше словами алгоритм, мне так понятнее будет. И по русски плиз, я в программерскую феню еще не до конца въезжаю.

Автор: Serenum 22.7.2004, 11:56
Alex101

А почему в цикле четыре прохода?

Автор: Alex101 22.7.2004, 12:03
Цитата(Serenum @ 22.7.2004, 08:56)
Alex101

А почему в цикле четыре прохода?

Больше не надо. Если надо перевернуть 8-и битное число, то идем до середины и меняем симметричные биты.

P.S.
Проверьте, работает? (Просто самому интересно, сейчас C нет, а в нашем языке нет операций сдвига).

Автор: <Spawn> 22.7.2004, 12:14
можешь функцию из Winsock исользовать, а именно ntohl, если я не правильно помню(если не то, то сморти htonl)

Автор: maxim1000 22.7.2004, 12:15
Цитата
Ребят, можете поподробнее объяснить, что вы предлагаете. Т. е, извлечено число из порта, присвоено переменной , и дальше словами алгоритм, мне так понятнее будет. И по русски плиз, я в программерскую феню еще не до конца въезжаю.

аналогия:
есть стопка книг
алгоритм такой:
1. взять верхнюю книгу и положить справа (там где должна быть перевернутая стопка)
2. повторить (1) столько раз, сколько книг в стопке
получится перевернутая стопка книг...

Автор: chipset 22.7.2004, 12:19
Код

#include <iostream>
using namespace std;
unsigned char mirror(unsigned char x)
{
unsigned char result=0;

for(int i=0;i<4;i++)
 result+=(((x<<i)&1)>>(7-i)+(((x<<(7-i))&1)>>i));

 return result;
}
void main () {
unsigned char x = 0xFA;
unsigned char r = mirror(x);
int i = (int)r;
cout<<i<<endl;
system("PAUSE");
}

Выводит ноль sad.gif

Автор: Guest 22.7.2004, 12:48
<Spawn>

Мне под DOS надо...


maxim1000


Цитата
аналогия:
есть стопка книг
алгоритм такой:
1. взять верхнюю книгу и положить справа (там где должна быть перевернутая стопка)
2. повторить (1) столько раз, сколько книг в стопке
получится перевернутая стопка книг...

Это все понятно, но поближе к Си, пжста?

Автор: oleg1973 22.7.2004, 12:54
кароче я так понимаю проблему
имеем байт
11110000
нада из него сделать
00001111

делаем
_asm
{
mov al,наш байт
rol al,4
}


получим че хотели

Автор: Hroft 22.7.2004, 13:03
Код

#include <iostream>

typedef int my_type;
const unsigned int my_type_size = sizeof(my_type) * 8;

void out_bits(my_type number)
{
       // служебная конкретная единица
       my_type my_1 = static_cast<my_type>(1);
       // цикл по всем битам
       for (int i=0;i<my_type_size;++i) {
               // если бит установлен - вывести единицу, иначе ноль
               if ((number & (my_1 << i)) != 0) {
                       std::cout<<"1";
               } else {
                       std::cout<<"0";
               }
       }
       std::cout<<"\n";
}

my_type rev_bits(my_type number)
{
       my_type res = 0;
       my_type my_1 = static_cast<my_type>(1);
       for (int i=0;i<my_type_size;++i) {
               if ((number & (my_1 << i)) != 0) {
                       // накапливаем в res, но сдвигаем не на позицию текущего бита,
                       // а на длину битового представления минус позицию - собственно
                       // инвертирование
                       res |= my_1 << (my_type_size - 1 - i);
               }
       }
       return res;
}

int main()
{
       my_type number = 43;
       out_bits(number);
       out_bits(rev_bits(number));
       return 0;
}

Криво, быть может, но вроде работает. Прямой подход, без премудростей.

Автор: Alex101 22.7.2004, 15:17
Цитата(oleg1973 @ 22.7.2004, 09:54)
кароче я так понимаю проблему
имеем байт
11110000
нада из него сделать
00001111

делаем
_asm
{
mov al,наш байт
rol al,4
}


получим че хотели

Это будет работать только для твоего примера.
Команда ROL осуществляет сдвиг влево + переносит старший бит в младший.
А тут надо зеркально отобразить, например: 10110011->11001101

Автор: maxim1000 22.7.2004, 15:25
Цитата
кароче я так понимаю проблему
имеем байт
11110000
нада из него сделать
00001111

делаем
_asm
{
mov al,наш байт
rol al,4
}

если человек сказал, что он на С только начинает, это еще не значит, что до этого он программировал на ассемблере biggrin.gif
Цитата
Это все понятно, но поближе к Си, пжста?

фрагмент
Код
  if(x&1)
    result++;

просто проверяет младший бит x, и если он 1, то добавляет его к result
Код
result<<=1;

сдвигает result влево на один бит (освобождает место для следующего)
Код
x>>=1;

сдвигает x вправо на один бит (делает младшим следующий)
вообще полезно было бы запустить все это в отладочнике и пройтись пошаговым выполнением...

Автор: Alex101 22.7.2004, 15:26
Цитата(chipset @ 22.7.2004, 09:19)
Выводит ноль sad.gif

А r чему равно перед присваиванием?
Да, int надо unsigned
(В этом примере нормально должно быть по-любому 5F, а так - может отрицательное число получиться)
Добавлено @ 15:34
Поставьте дополнительные скобки.

Автор: Girder 22.7.2004, 16:08
Код

_asm
{push eax
 push ebx
 mov al, Входной байт
 mov ah,al
 ror al,1
 rol ah,1
 mov bx,ax
 rol bh,2
 ror bl,2
 and ax,1188h
 and bx,2244h
 or ax,bx
 or al,ah
 mov Зеркальный байт,al
 pop ebx
 pop eax}

Автор: oleg1973 22.7.2004, 20:02
Alex101
а ну да чета я ступил sad.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)