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


Автор: TheDestroyer 10.4.2009, 12:34
Подскажите пожалуйста, возможно ли присваивать переменным значение в битовом представлении?
Т.е. что бы писать не
Код

char a;
a = 2;

а
Код

char a;
a = 00000010;


Автор: InvalidProperty 10.4.2009, 12:46
хм... у меня не получилось ни в MS VS 2005, ни под gcc 4.1.2, хотя нашел такую информацию

http://mandrivausers.org/index.php?showtopic=9326
http://www.gursey.gov.tr/Gilgamesh-WWW/IntelCompDocs/ref/cnst_c.htm

Автор: Lazin 10.4.2009, 12:50
Код

template <unsigned long N>
struct binary
{
   static unsigned const value = binary<N/10>::value << 1 | N % 10;                    
};

template <>                           
struct binary<0>
{
   static unsigned const value = 0;
};

char a = binary<10>::value;

Автор: UniBomb 10.4.2009, 12:54
Код

char a;
a = 0b00000010; //двоичное представление

char b;
b = 0x01; //шестнадцатеричное представление


кажеться я не туда пишу....

Автор: Lazin 10.4.2009, 13:23
Цитата(UniBomb @  10.4.2009,  12:54 Найти цитируемый пост)
0b00000010

а где такое работает?

Автор: Acer 10.4.2009, 13:32
Lazin, мож свой компилятор юзает smile

0x00000010 - эт аж никак не 2

Автор: UniBomb 10.4.2009, 14:43
Lazin, avr-gcc 4.3.0 smile

Автор: UniBomb 10.4.2009, 15:22
Acer, преффикс "0b" насколько я знаю не включон в стандарты (я имею в языках С и С++), поэтому вполне возможно что эта штука не везде работает. Такая конструкция встречается в основном в старых компиляторах и в компиляторах для микропроцессорах. avr-gcc как раз к последнему и относится, ведь в этой области было бы странно, еслибы такая конструкция не поддерживалась бы ;)

Автор: math64 11.4.2009, 20:11
Код

#define BIN0000 0
#define BIN0001 1
#define BIN0010 2
#define BIN0011 3
#define BIN0100 4
#define BIN0101 5
#define BIN0110 6
#define BIN0111 7
#define BIN1000 8
#define BIN1001 9
#define BIN1010 10
#define BIN1011 11
#define BIN1100 12
#define BIN1101 13
#define BIN1110 14
#define BIN1111 15
#define BIN8(a,b) (((BIN##a)<<4) | (BIN##b))
#define BIN16(a,b,c,d) ((BIN8(a,b)<<8) | BIN8(c,d))
#define BIN32(a,b,c,d,e,f,g,h) ((BIN16(a,b,c,d)<<16) | BIN16(e,f,g,h))

Автор: Riddik 12.4.2009, 02:01
 smile  как много я ещё не знаю, а уже не один месяц учу... :(

Автор: UniBomb 13.4.2009, 09:17
И ещё как вариант:

Код

char c;

c = 1<<1; // c = 2;

c = ((1 << 7)|(1 << 5)|(1 << 3)|(1 << 1)); // c = 170;

Автор: Anikmar 13.4.2009, 10:15
Чего только люди не придумают, чтобы свой код сделать нечитаемым.

Автор: UniBomb 13.4.2009, 10:20
Anikmar, Последний вариант кстате самый читаемый, если "с" - это набор флагов. И если эти флаги как то именованны, то нет ничего более читаемого, чем:

Код

TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

Автор: andrew_121 13.4.2009, 11:35
Цитата(Lazin @  10.4.2009,  13:23 Найти цитируемый пост)
а где такое работает? 

В Ассемблере точно работает.

Автор: TheDestroyer 13.4.2009, 12:33
Спасибо, да, похоже, прямого задания в бинарном виде числа в таких средах как Borland C++ и VC нет.

Автор: mes 13.4.2009, 12:38
Цитата(UniBomb @  13.4.2009,  09:20 Найти цитируемый пост)
Последний вариант кстате самый читаемый, если "с" - это набор флагов. И если эти флаги как то именованны, то нет ничего более читаемого, чем:
Код

TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

а как насчет такой записи ?

Код

TWCR = ТWINT | TWSTA | TWEN;

неужто менее читаема ?  smile 
к тому же еще обладает большей гибкостью, так как одно название может объединять несколько флагов. smile

Автор: UniBomb 13.4.2009, 12:44
mes, ну можно и так. В принципе то это одно и тоже...

Автор: J0ker 13.4.2009, 16:07
выучить:

ноль
0000b == 0x0

степени двойки
0001b == 0x1
0010b == 0x2
0100b == 0x4
1000b == 0x8

любая комбинация битов получается путем суммирования вышеозначенного
т.о. каждые 4 бита выражаются одной 16-тиричной цифрой, т.е.:
Код

01100011110011000111001110111101
0110     0011     1100     1100     0111         0011     1011         1101
0x4+0x2  0x2+0x1  0x8+0x4  0x8+0x4  0x4+0x2+0x1  0x2+0x1  0x8+0x4+0x2 0x8+0x4+0x1
0x6      0x3      0xC      0xC      0x7          0x3      0xE          0XD
0x63CC73ED

Автор: Anikmar 13.4.2009, 18:04
Цитата(UniBomb @  13.4.2009,  10:20 Найти цитируемый пост)
Anikmar, Последний вариант кстате самый читаемый, если "с" - это набор флагов. И если эти флаги как то именованны, то нет ничего более читаемого, чем:


А так хуже читается?
Код

#define Flag1 1
#define Flag2 2
#define Flag3 4
#define Flag4 8
#define Flag5 16
#define Flag6 32

// Кому не нравятся #define можно const, enum - без разницы
unsigned int MyMask;

MyMask = Flag1|Flag2|Flag3;

....

if (MyMask&Flag1) { // установлен флаг1 }




Автор: mes 13.4.2009, 20:05
Цитата(Anikmar @  13.4.2009,  17:04 Найти цитируемый пост)
А так хуже читается?

а вот тут как раз лучше бы выглядело в "развернутом виде"
Код

#define Flag1 ( 1 << 0 )
#define Flag2 ( 1 << 1 )
#define Flag3 ( 1 << 2 )
#define Flag4 ( 1 << 3 )
#define Flag5 ( 1 << 4 )
#define Flag6 ( 1 << 5 )


Цитата(Anikmar @  13.4.2009,  17:04 Найти цитируемый пост)
// Кому не нравятся #define можно const, enum - без разницы

разница есть, но это уже не по теме smile


Автор: Anikmar 13.4.2009, 21:17
Цитата(mes @  13.4.2009,  20:05 Найти цитируемый пост)
а вот тут как раз лучше бы выглядело в "развернутом виде"

Почему? Чисто для восприятия номер бита видеть?

Если это не в тысяче мест в коде используется - можно и в развернутом. А так компилятору лишние вычисления - ведь вряд-ли он их кешировать будет.

Автор: mes 13.4.2009, 21:33
Цитата(Anikmar @  13.4.2009,  20:17 Найти цитируемый пост)

Почему? Чисто для восприятия номер бита видеть?

да.. для восприятия,  гораздо легче проследить за правильностью ряда 0,1,2,3,4,5, чем 1,2,4,8,16,32.  smile 


Цитата(Anikmar @  13.4.2009,  20:17 Найти цитируемый пост)
Если это не в тысяче мест в коде используется - можно и в развернутом. А так компилятору лишние вычисления - ведь вряд-ли он их кешировать будет. 

Это Вы про этап компиляции ? сделайте вместо #define enum  и вычислится все в одном месте.  smile 




Автор: Anikmar 13.4.2009, 21:42
Цитата(mes @  13.4.2009,  21:33 Найти цитируемый пост)
да.. для восприятия,  гораздо легче проследить за правильностью ряда 0,1,2,3,4,5, чем 1,2,4,8,16,32.   

Ехидный вопрос: а оно надо? 
Чего за правильностью такого ряда следить - он никуда не денется и правильность свою за углом не продаст  smile 
И надо ли знать конкретно знать номер бита, который устанавлиает флаг с именем fEnableMixedMode?  smile 

А в общем - оба подходы правильны, ошибок не содержат, так что - кому что нравится  smile 

Автор: mes 13.4.2009, 22:27
Цитата(Anikmar @  13.4.2009,  20:42 Найти цитируемый пост)
Ехидный вопрос: а оно надо? 

мне кажется Вы почувствуйте это,  если представите что Вы реализуете набор флагов по документации ( в которой сказано какому биту соответствует каждый флаг)
ну и битов больше чем 8 , к примеру 32..

P.S. а код впоследствии должен быть проверен "ревизором" (если Вам вдруг приятно было вспомнить таблицу умножения, то "ревизору" подобная гимнастика ума может оказаться не кстати) 
 smile 

Автор: Anikmar 13.4.2009, 23:24
Цитата(mes @  13.4.2009,  22:27 Найти цитируемый пост)
P.S. а код впоследствии должен быть проверен "ревизором" (если Вам вдруг приятно было вспомнить таблицу умножения, то "ревизору" подобная гимнастика ума может оказаться не кстати) 

Ни разу не сталкивался с ревизором кода - наверное страшная личность  smile 
Для него специально я бы сделал как-нибудь так:
Код

#define Flag1 (45869/(32758 + 12931))
#define Flag2 ( (852369-456987)/197691 )
и т.д.

 smile 

Автор: J0ker 13.4.2009, 23:27
Anikmar, дефайны - это зло

Автор: Anikmar 13.4.2009, 23:32
Цитата(J0ker @  13.4.2009,  23:27 Найти цитируемый пост)
Anikmar, дефайны - это зло 

Без дефайнов никуда. Смотря где и как их использовать - где-то зло, а где-то без них не обойтись.
В данном случае спорить не буду - просто для понятности набрал. Лично я использовал бы enum, о чем и сделал оговорку.

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