C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Байты и биты, как увидеть?
Лена
Отправлено: 08.02.2006, 12:12


Мастер участка

Группа: Участник
Сообщений: 501



От внешнего устройства приходит число типа Int32. Существует битовая 4-х байтная маска. Каждый бит этой 4-х байтовой маски что-то обозначает. Например, 7-й бит первого байта указывает на то, что произошла остановка определенного датчика.
Мой вопрос в том, как мне разложить мое пришедшее число на эти самый 4 байта и посмотреть какие биты у него установлены и затем согласно существующей битовой маски сравнить и вывести нужные сообщения?
Rius
Отправлено: 08.02.2006, 12:21


Мастер участка

Группа: Участник
Сообщений: 321



логическое И: &
число & маска, плюс можно еще сделать сдвиг>>

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

можно еще перевести число в строку, где каждый символ соответствует биту.
Лена
Отправлено: 08.02.2006, 12:29


Мастер участка

Группа: Участник
Сообщений: 501



Дело в том, что я никогда не работала на уровне битов и байтов, а тут озадачили. sad.gif

>можно еще перевести число в строку, где каждый символ соответствует биту.

Вот это, как я понимаю, мне и нужно сделать, но как?
Увидев число в его битовом виде я решу, как мне кажется, мой вопрос.
klen
Отправлено: 08.02.2006, 12:41


Машинист паровоза

Группа: Участник
Сообщений: 239



QUOTE (Лена @ 08/02/2006, 12:29)
>можно еще перевести число в строку, где каждый символ соответствует биту.

Вот это, как я понимаю, мне и нужно сделать, но как?
Увидев число в его битовом виде я решу, как мне кажется, мой вопрос.

CODE

int BitContainer = ЧИСЛО КОТОРОЕ ВЫ ПРИНИМАЕТЕ

AnsiString BitSetStr;
for (int Bit=0; Bit<32; Bit++)
{
   // тест установки младшего бита
   i if ( BitContainer & 1 )  BitSetStr = AnsiString("1") + BitSetStr;
   else                              BitSetStr = AnsiString("0") + BitSetStr;
   BitContainer >>= 1;
}
// выводите для просмотра
Label->Caption=BitSetStr;


Отредактировано klen — 08/02/2006, 12:41
viva
Отправлено: 08.02.2006, 12:44


Дежурный стрелочник

Группа: Участник
Сообщений: 31



[CODE]
unsigned long mask=0x00000001;
if(digit & mask) first_action(); mask <<= 1;
if(digit & mask) second_action(); mask <<= 1;
...
Konstantine
Отправлено: 08.02.2006, 14:34


Мастер участка

Группа: Модератор
Сообщений: 545



CODE
union
{   int INT;
    struct {
        unsigned bit1:1; // это называется "битовые поля"
        unsigned bit1:1;
        unsigned bit1:1;
        unsigned bit1:1;
        unsigned bit1:1;
        unsigned bit1:1;
        .....} bit;

} bits;
} UN

тогда загружаешь так:
CODE
UN.INT=4532;//или нужное значение

а получить биты так:
CODE
n=UN.bits.bit1;

также после того как загрузишь — можно и в отладчике биты смотреть
Лена
Отправлено: 08.02.2006, 14:48


Мастер участка

Группа: Участник
Сообщений: 501



Cпасибо всем большое за ответы!
Буду разбираться дальше, пока остановилась на варианте от пользователя klen. Он для меня самый понятный. smile.gif
Проверила, работает!
olegenty
Отправлено: 08.02.2006, 14:52


Ветеран

Группа: Модератор
Сообщений: 2412



метод Константина самы удобный (и во много раз более понятный, потому что очевидный) smile.gif

только биты будут называться по-разному, а не все "bit1"

Отредактировано olegenty — 08/02/2006, 15:52
Лена
Отправлено: 08.02.2006, 14:58


Мастер участка

Группа: Участник
Сообщений: 501



Дело в том, что я делаю это в специлизированной программе, которая поддреживает внутренний усеченный C++. В нем нет многих вещей, например, union. Я чуть подправила метод от klein и все заработало.
smile.gif
Doga
Отправлено: 08.02.2006, 15:25


Мастер участка

Группа: Участник
Сообщений: 575



Мне кажется, что перевод байтов в строку не оптимальное решение.

Если дело только в недостаточной наглядности обрабатываемых байтов, то я бы сделал бы так:

CODE

//Bin.hpp
//Представление байта в двоичном виде

#define b00000000  0x00
#define b00000001  0x01
#define b00000010  0x02
#define b00000011  0x03
#define b00000100  0x04
#define b00000101  0x05
#define b00000110  0x06
#define b00000111  0x07
#define b00001000  0x08
#define b00001001  0x09

//... ну и так далее до

#define b11111111  0xFF //255


Сгенерировать такой файл труда не составит, особенно если воспользоваться кодом klensmile.gif

Подключите этот файл к своему модулю и ... (ну, хотя бы, попробуйте smile.gif )

Такой подход к проблеме обеспечит максимальную наглядность и, при этом, не увеличит временные затраты на преобразование данных.
Grigoriy
Отправлено: 09.02.2006, 00:20


Мастер участка

Группа: Участник
Сообщений: 381



CODE

void visionbits32(unsigned int s, char* masb)
{
asm{
cld;
mov edi,masb;
mov ecx,32;
mov edx,s;
@1:xor eax,eax;
rcr edx,1;
rcl eax,1;
stosb;
loop @1;
};
};


Для массива masb должна быть предварительно выделена память размером 32 байта.
Возвращаются в массиве соответственно значения 0 или 1.

Вернуться в Вопросы программирования в C++Builder