Как вставлять в программу на C++ двоичные константы?
От: Александр Шаргин Россия RSDN.ru
Дата: 29.12.01 01:36
Оценка: 105 (5) +1
Статья:
Как вставлять в программу на C++ двоичные константы?
Автор(ы): Александр Шаргин
Дата: 01.12.2001


Авторы:
Александр Шаргин

Аннотация:
В языке C++ есть восьмеричные, десятичные и шестнадцатеричные константы. А двоичных — нет. Тем не менее, при помощи препроцессора можно соорудить макрос, который позволит нам смоделировать такие константы. Основная идея — преобразовывать восьмеричную константу в двоичную, выделяя из неё отдельные цифры и умножая их на соответствующий весовой коэффициент.
--
Я думал, ты огромный страшный Бажище,
А ты недоучка, крохотный Бажик...
Зачем???
От: DarkOne Латвия http://darkone.yo.lv
Дата: 09.06.02 07:57
Оценка: 9 (5) +3 :))) :)
Зачем вообще такой геморой нужен. По-моему только усложнение программы. Вообще госпрода программисты запомните таблицу из 16 элементов:
0000 — 0
0001 — 1
0010 — 2
0011 — 3
0100 — 4
0101 — 5
0110 — 6
0111 — 7
1000 — 8
1001 — 9
1010 — A
1011 — B
1100 — C
1101 — D
1110 — E
1111 — F

и никаких проблемм с переводом BIN->HEX (10110010b -> 1011 0010 -> 0xB2)
--
Keep on coding...
Двоичные константы
От: Valery  
Дата: 30.12.01 01:36
Оценка:
Давно хочу спросить как насчет
#define IPOPT_SEC_CONF 0x1111000100110101b?
Re: Двоичные константы
От: odisseyLM  
Дата: 14.01.02 03:31
Оценка:
Ну и че ты написал, шестнадцатеричную константу в 9 байт.
Re: Как вставлять в программу на C++ двоичные константы?
От: BioUnit Россия  
Дата: 17.11.03 12:26
Оценка: :)
Не скажу, что придумавыл его для дела. Так, ради интереса.
template<unsigned __int64 bin>
class CToDec
{
public: 
    enum { value = (bin&1) + 2*CToDec<bin/10>::value };
};

template<>
class CToDec<0>
{
public: enum { value = 0 };
};

#define BIN(bin) CToDec<bin>::value
Re[2]: Как вставлять в программу на C++ двоичные константы?
От: BioUnit Россия  
Дата: 17.11.03 15:24
Оценка:
В принципе, т.о. можно приводить к десятичному из любого значения:
template<int base, u64 bin>
class CToDec
{
public: 
    enum { value = (bin&0xF) + base*CToDec<bin/0x10>::value };
};

template<int base>
class CToDec<base,0>
{
public: enum { value = 0 };
};

#define BIN2DEC(bin) CToDec<2,0x##bin>::value
#define OCX2DEC(bin) CToDec<8,0x##bin>::value
#define PNT2DEC(bin) CToDec<5,0x##bin>::value

Только для VC придется портировать:
template<u64 bin, int base=2>
class CToDec
{
private:
    template<u64 pin> class CPort
    {
    public: enum { value = CToDec<pin, base>::value };
    };

    template<> class CPort<0>
    {
    public: enum { value = 0 };
    };

public:
    enum { value = ((bin&0xF) + base*CPort<bin/0x10>::value) };
};

Правда обнаружилась ошибка компилятора (или предкомпилятора): он невсегда правильно делит u64 на 16.
Re[2]: Как вставлять в программу на C++ двоичные константы?
От: Аноним  
Дата: 29.12.03 15:49
Оценка:
Здравствуйте, BioUnit, Вы писали:

BU>Не скажу, что придумавыл его для дела. Так, ради интереса.

Такое придумывали и несколько раньше...

http://www.rsdn.ru/Forum/Message.aspx?mid=218608
Автор: TepMuHyc
Дата: 19.03.03
Re: Как вставлять в программу на C++ двоичные константы?
От: Аноним  
Дата: 05.08.04 06:35
Оценка:
Немного подумал, почитал что есть на форуме и все такое. Вот мой вариант. Хотя от и содержит макрос, но вызывает ошибку компиляции при любом неверном формате параметра и позволяет использовать максимум 22 двоичных разряда.


#include <boost/static_assert.hpp>

template <long long Num>
struct BitConst
    {
    enum { result = 2*(BitConst<Num/8>::result) + Num%8 };
    BOOST_STATIC_ASSERT(Num%8 < 2);
    };
    
template <>
struct BitConst<0l>
    {
    enum { result = 0 };
    };

#define BIT_CONST(i) BitConst<(0##i##l)>::result
Re: Зачем???
От: Kluev  
Дата: 05.08.04 07:23
Оценка: +3
Здравствуйте, DarkOne, Вы писали:

DO>Зачем вообще такой геморой нужен. По-моему только усложнение программы. Вообще госпрода программисты запомните таблицу из 16 элементов:


Обычно если и использую битовые константы то в основном как маски флагов, а их весьма удобно задавать так

enum {
    accessRead    = 1 << 0, // 0001
    accessWrite    = 1 << 1, // 0010
    accessRW        = accessRead | accessWrite // 0011
};
Re: Ответ Boost'a
От: Pavel Chikulaev Россия  
Дата: 06.11.05 18:05
Оценка:

Scott Schurr's version is in http://boost-consulting.com/vault/ (file
binary_int.zip).
It can be used as:
unsigned int regValue2 = binary_int<1000,1001,0011,0000>::value;


Matt Calabrese's version is in
http://www.illegal-immigration.com/Riv/boost/binary_literal2.hpp.
It can be used as:
int x = BOOST_BINARY_LITERAL( 101 0111 1010 0110 );

Re: Как вставлять в программу на C++ двоичные константы?
От: DmSh Россия  
Дата: 04.11.06 20:50
Оценка:
Вот еще вариант ради интереса

const u8 bc = BIN8(10110111);
const u16 bs = BIN16(10101111,11110011);
const u32 bi3 = BIN24(10101111,11110011,11110011);
const u32 bi4 = BIN32(10101111,11110011,11110011,10001000);
const u64 bll5 = BIN40(10101111,11110011,11110011,10001000,10000000);
const u64 bll6 = BIN48(10100000,10001000,10000000,00000001,10000000,00000001);
const u64 bll7 = BIN56(10000000,01000001,10000000,00000001,10000000,00000001,10000000);
const u64 bll8 = BIN64(10000000,00000001,10000000,00000001,10000000,00000001,10000000,00000001);

Здесь проверяеться все
т.е. при задании константы обязательно надо указывать 8 цифр и только "0" и "1"
нельзя, написать, допустим
BIN(10000020) — неверный символ "2"
BIN8(00000), BIN8(00010) — 5 символов, а должнобыть 8
BIN8(000000000) — 9 символов, а должнобыть 8


#define __TO_BIN(x) (convertors::_byte_length_check<u64,0x1##x,0x100000000,0x111111111>::value)
#define BIN(type,x1,x2,x3,x4,x5,x6,x7,x8) (convertors::bin_val<type,__TO_BIN(x1),__TO_BIN(x2),__TO_BIN(x3), \
__TO_BIN(x4),__TO_BIN(x5),__TO_BIN(x6),__TO_BIN(x7),__TO_BIN(x8)>::value)

#define BIN64(x1,x2,x3,x4,x5,x6,x7,x8) BIN(u64,x1,x2,x3,x4,x5,x6,x7,x8)
#define BIN56(x1,x2,x3,x4,x5,x6,x7) BIN(u64, 00000000, x1,x2,x3,x4,x5,x6,x7)
#define BIN48(x1,x2,x3,x4,x5,x6) BIN(u64, 00000000, 00000000, x1,x2,x3,x4,x5,x6)
#define BIN40(x1,x2,x3,x4,x5) BIN(u64, 00000000, 00000000, 00000000, x1,x2,x3,x4,x5)
#define BIN32(x1,x2,x3,x4) BIN(u32, 00000000, 00000000, 00000000, 00000000, x1,x2,x3, x4)
#define BIN24(x1,x2,x3) BIN(u32, 00000000, 00000000, 00000000, 00000000, 00000000, x1,x2,x3)
#define BIN16(x1,x2) BIN(u16, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000,x1,x2)
#define BIN8(x1) BIN( u8, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, x1)

namespace convertors
{
template<bool bFlag, typename T, typename U> struct SelectType { typedef T Result; };
template<typename T, typename U> struct SelectType<false, T, U> { typedef U Result; };

template <class From, class To> To safe_convert(From _val) { assert(To(_val)==_val); return To(_val); }

template<class T, T _val, T _min, T _max, bool bInRange=(_val>=_min && _val<=_max)> struct _byte_length_check {};
template<class T, T _val, T _min, T _max>
struct _byte_length_check<T,_val,_min,_max,true> { enum {value=_val-_min}; };

#if _MSC_VER >=1400

template<class T, int _val>
struct bin_val_t
{
template<int val> struct _bit_val;
template<> struct _bit_val<0> { enum : T {ival=0};};
template<> struct _bit_val<1> { enum : T {ival=1};};
template<int _val> struct _bin_val;
template<int _val> struct _bin_val<_val>
{ enum : T { value=_bit_val<(_val%0x10)>::ival+(_bin_val<(_val/0x10)>::value*2)};};
template<> struct _bin_val<0> { enum : T {value=0};};
template<> struct _bin_val<1> { enum : T {value=1};};
enum : T { value=_bin_val<_val>::value };
};

template <class T, int x1, int x2=-1, int x3=-1, int x4=-1, int x5=-1, int x6=-1, int x7=-1, int x8=-1>
class bin_val {
enum { b1=bin_val_t<u8,x1>::value, b2=bin_val_t<u8,x2>::value, b3=bin_val_t<u8,x3>::value,
b4=bin_val_t<u8,x4>::value, b5=bin_val_t<u8,x5>::value, b6=bin_val_t<u8,x6>::value,
b7=bin_val_t<u8,x7>::value, b8=bin_val_t<u8,x8>::value };
public:
enum : T { value=((u64(b1)<<56)+(u64(b2)<<48)+(u64(b3)<<40)+(u64(b4)<<32)+(u64(b5)<<24)+
(u64(b6)<<16)+(u64(b7)<<8)+u64(b8)) };
};

#else // _MSC_VER >=1400

template<typename To, class From, From _val>
struct ConvertInt { static typename SelectType<To(_val)==_val,To,From>::Result value; };
template<typename To, typename From, From _val>
typename SelectType<To(_val)==_val,To,From>::Result ConvertInt<To,From,_val>::value=_val;

template<class T,int _val>
struct bin_val_t{
template<int val> struct _bit_val;
template<> struct _bit_val<0> { enum {ival=0};};
template<> struct _bit_val<1> { enum {ival=1};};
template<int _val> struct _bin_val;
template<int _val> struct _bin_val<_val> { enum { value=_bit_val<(_val%0x10)>::ival+
(_bin_val<(_val/0x10)>::value*2)};}
template<> struct _bin_val<0> { enum {value=0};};
template<> struct _bin_val<1> { enum {value=1};};
enum { value=_bin_val<_val>::value };
};

template <class T, int x1, int x2=-1, int x3=-1, int x4=-1, int x5=-1, int x6=-1, int x7=-1, int x8=-1>
class bin_val {
enum { b1=bin_val_t<u8,x1>::value, b2=bin_val_t<u8,x2>::value, b3=bin_val_t<u8,x3>::value,
b4=bin_val_t<u8,x4>::value, b5=bin_val_t<u8,x5>::value, b6=bin_val_t<u8,x6>::value,
b7=bin_val_t<u8,x7>::value, b8=bin_val_t<u8,x8>::value, };
public:
static const T value;
};
template <class T, int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8>
const T bin_val<T,x1,x2,x3,x4,x5,x6,x7,x8>::value=
ConvertInt<T,u64,((u64(b1)<<56)+(u64(b2)<<48)+(u64(b3)<<40)+(u64(b4)<<32)+(u64(b5)<<24)+(u64(b6)<<16)+
(u64(b7)<<8)+u64(b8))>::value;

#endif // _MSC_VER >=1400

}; //namespace convertors
Re[2]: Как вставлять в программу на C++ двоичные константы?
От: Smooky Россия  
Дата: 08.02.07 08:05
Оценка:
Здравствуйте, DmSh, Вы писали:

MSVC6.0 НЕ КОМПИЛЯЕТ ЭТО!

DS>Вот еще вариант ради интереса


DS>const u8 bc = BIN8(10110111);

DS>const u16 bs = BIN16(10101111,11110011);
DS>const u32 bi3 = BIN24(10101111,11110011,11110011);
DS>const u32 bi4 = BIN32(10101111,11110011,11110011,10001000);
DS>const u64 bll5 = BIN40(10101111,11110011,11110011,10001000,10000000);
DS>const u64 bll6 = BIN48(10100000,10001000,10000000,00000001,10000000,00000001);
DS>const u64 bll7 = BIN56(10000000,01000001,10000000,00000001,10000000,00000001,10000000);
DS>const u64 bll8 = BIN64(10000000,00000001,10000000,00000001,10000000,00000001,10000000,00000001);

DS>Здесь проверяеться все

DS>т.е. при задании константы обязательно надо указывать 8 цифр и только "0" и "1"
DS>нельзя, написать, допустим
DS>BIN(10000020) — неверный символ "2"
DS>BIN8(00000), BIN8(00010) — 5 символов, а должнобыть 8
DS>BIN8(000000000) — 9 символов, а должнобыть 8


DS>#define __TO_BIN(x) (convertors::_byte_length_check<u64,0x1##x,0x100000000,0x111111111>::value)

DS>#define BIN(type,x1,x2,x3,x4,x5,x6,x7,x8) (convertors::bin_val<type,__TO_BIN(x1),__TO_BIN(x2),__TO_BIN(x3), \
DS>__TO_BIN(x4),__TO_BIN(x5),__TO_BIN(x6),__TO_BIN(x7),__TO_BIN(x8)>::value)

DS>#define BIN64(x1,x2,x3,x4,x5,x6,x7,x8) BIN(u64,x1,x2,x3,x4,x5,x6,x7,x8)

DS>#define BIN56(x1,x2,x3,x4,x5,x6,x7) BIN(u64, 00000000, x1,x2,x3,x4,x5,x6,x7)
DS>#define BIN48(x1,x2,x3,x4,x5,x6) BIN(u64, 00000000, 00000000, x1,x2,x3,x4,x5,x6)
DS>#define BIN40(x1,x2,x3,x4,x5) BIN(u64, 00000000, 00000000, 00000000, x1,x2,x3,x4,x5)
DS>#define BIN32(x1,x2,x3,x4) BIN(u32, 00000000, 00000000, 00000000, 00000000, x1,x2,x3, x4)
DS>#define BIN24(x1,x2,x3) BIN(u32, 00000000, 00000000, 00000000, 00000000, 00000000, x1,x2,x3)
DS>#define BIN16(x1,x2) BIN(u16, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000,x1,x2)
DS>#define BIN8(x1) BIN( u8, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 00000000, x1)

DS>namespace convertors

DS>{
DS> template<bool bFlag, typename T, typename U> struct SelectType { typedef T Result; };
DS> template<typename T, typename U> struct SelectType<false, T, U> { typedef U Result; };

DS> template <class From, class To> To safe_convert(From _val) { assert(To(_val)==_val); return To(_val); }


DS> template<class T, T _val, T _min, T _max, bool bInRange=(_val>=_min && _val<=_max)> struct _byte_length_check {};

DS> template<class T, T _val, T _min, T _max>
DS> struct _byte_length_check<T,_val,_min,_max,true> { enum {value=_val-_min}; };

DS>#if _MSC_VER >=1400


DS> template<class T, int _val>

DS> struct bin_val_t
DS> {
DS> template<int val> struct _bit_val;
DS> template<> struct _bit_val<0> { enum : T {ival=0};};
DS> template<> struct _bit_val<1> { enum : T {ival=1};};
DS> template<int _val> struct _bin_val;
DS> template<int _val> struct _bin_val<_val>
DS> { enum : T { value=_bit_val<(_val%0x10)>::ival+(_bin_val<(_val/0x10)>::value*2)};};
DS> template<> struct _bin_val<0> { enum : T {value=0};};
DS> template<> struct _bin_val<1> { enum : T {value=1};};
DS> enum : T { value=_bin_val<_val>::value };
DS> };

DS> template <class T, int x1, int x2=-1, int x3=-1, int x4=-1, int x5=-1, int x6=-1, int x7=-1, int x8=-1>

DS> class bin_val {
DS> enum { b1=bin_val_t<u8,x1>::value, b2=bin_val_t<u8,x2>::value, b3=bin_val_t<u8,x3>::value,
DS> b4=bin_val_t<u8,x4>::value, b5=bin_val_t<u8,x5>::value, b6=bin_val_t<u8,x6>::value,
DS> b7=bin_val_t<u8,x7>::value, b8=bin_val_t<u8,x8>::value };
DS> public:
DS> enum : T { value=((u64(b1)<<56)+(u64(b2)<<48)+(u64(b3)<<40)+(u64(b4)<<32)+(u64(b5)<<24)+
DS> (u64(b6)<<16)+(u64(b7)<<8)+u64(b8)) };
DS> };

DS>#else // _MSC_VER >=1400


DS> template<typename To, class From, From _val>

DS> struct ConvertInt { static typename SelectType<To(_val)==_val,To,From>::Result value; };
DS> template<typename To, typename From, From _val>
DS> typename SelectType<To(_val)==_val,To,From>::Result ConvertInt<To,From,_val>::value=_val;

DS> template<class T,int _val>

DS> struct bin_val_t{
DS> template<int val> struct _bit_val;
DS> template<> struct _bit_val<0> { enum {ival=0};};
DS> template<> struct _bit_val<1> { enum {ival=1};};
DS> template<int _val> struct _bin_val;
DS> template<int _val> struct _bin_val<_val> { enum { value=_bit_val<(_val%0x10)>::ival+
DS> (_bin_val<(_val/0x10)>::value*2)};}
DS> template<> struct _bin_val<0> { enum {value=0};};
DS> template<> struct _bin_val<1> { enum {value=1};};
DS> enum { value=_bin_val<_val>::value };
DS> };

DS> template <class T, int x1, int x2=-1, int x3=-1, int x4=-1, int x5=-1, int x6=-1, int x7=-1, int x8=-1>

DS> class bin_val {
DS> enum { b1=bin_val_t<u8,x1>::value, b2=bin_val_t<u8,x2>::value, b3=bin_val_t<u8,x3>::value,
DS> b4=bin_val_t<u8,x4>::value, b5=bin_val_t<u8,x5>::value, b6=bin_val_t<u8,x6>::value,
DS> b7=bin_val_t<u8,x7>::value, b8=bin_val_t<u8,x8>::value, };
DS> public:
DS> static const T value;
DS> };
DS> template <class T, int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8>
DS> const T bin_val<T,x1,x2,x3,x4,x5,x6,x7,x8>::value=
DS> ConvertInt<T,u64,((u64(b1)<<56)+(u64(b2)<<48)+(u64(b3)<<40)+(u64(b4)<<32)+(u64(b5)<<24)+(u64(b6)<<16)+
DS> (u64(b7)<<8)+u64(b8))>::value;

DS>#endif // _MSC_VER >=1400


DS>}; //namespace convertors
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.