我需要处理一个二进制数。

我试着写:

const char x = 00010000;

但这并没有起作用。

我知道我可以使用与00010000值相同的十六进制数,但我想知道在c++中是否有用于二进制数的类型,如果没有,是否有其他解决方案?


当前回答

从c++ 14开始,你可以使用二进制字面值,现在它们是语言的一部分:

unsigned char a = 0b00110011;

其他回答

c++的过度工程思维已经在这里的其他答案中得到了很好的解释。以下是我尝试用C,保持简单的心态来做这件事:

unsigned char x = 0xF; // binary: 00001111

我扩展了@renato-chandelier给出的好答案,确保了以下方面的支持:

_NIBBLE_(…)- 4位,1位作为参数 _BYTE_(…)- 8位,2位作为参数 _sla_(…)- 12位,3个小块作为参数 _WORD_(…)- 16位,4位作为参数 _QUINTIBBLE_(…)- 20位,5个小块作为参数 _DSLAB_(…)- 24位,6个小块作为参数 _SEPTIBBLE_(…)- 28位,7位作为参数 _DWORD_(…)- 32位,8个小块作为参数

实际上,我对“quintibble”和“septibble”这两个词不太确定。如果有人有其他选择,请告诉我。

下面是重写的宏:

#define __CAT__(A, B) A##B
#define _CAT_(A, B) __CAT__(A, B)

#define __HEX_0000 0
#define __HEX_0001 1
#define __HEX_0010 2
#define __HEX_0011 3
#define __HEX_0100 4
#define __HEX_0101 5
#define __HEX_0110 6
#define __HEX_0111 7
#define __HEX_1000 8
#define __HEX_1001 9
#define __HEX_1010 a
#define __HEX_1011 b
#define __HEX_1100 c
#define __HEX_1101 d
#define __HEX_1110 e
#define __HEX_1111 f

#define _NIBBLE_(N1) _CAT_(0x, _CAT_(__HEX_, N1))
#define _BYTE_(N1, N2) _CAT_(_NIBBLE_(N1), _CAT_(__HEX_, N2))
#define _SLAB_(N1, N2, N3) _CAT_(_BYTE_(N1, N2), _CAT_(__HEX_, N3))
#define _WORD_(N1, N2, N3, N4) _CAT_(_SLAB_(N1, N2, N3), _CAT_(__HEX_, N4))
#define _QUINTIBBLE_(N1, N2, N3, N4, N5) _CAT_(_WORD_(N1, N2, N3, N4), _CAT_(__HEX_, N5))
#define _DSLAB_(N1, N2, N3, N4, N5, N6) _CAT_(_QUINTIBBLE_(N1, N2, N3, N4, N5), _CAT_(__HEX_, N6))
#define _SEPTIBBLE_(N1, N2, N3, N4, N5, N6, N7) _CAT_(_DSLAB_(N1, N2, N3, N4, N5, N6), _CAT_(__HEX_, N7))
#define _DWORD_(N1, N2, N3, N4, N5, N6, N7, N8) _CAT_(_SEPTIBBLE_(N1, N2, N3, N4, N5, N6, N7), _CAT_(__HEX_, N8))

下面是Renato举的例子:

char b = _BYTE_(0100, 0001); /* equivalent to b = 65; or b = 'A'; or b = 0x41; */
unsigned int w = _WORD_(1101, 1111, 0100, 0011); /* equivalent to w = 57155; or w = 0xdf43; */
unsigned long int dw = _DWORD_(1101, 1111, 0100, 0011, 1111, 1101, 0010, 1000); /* Equivalent to dw = 3745774888; or dw = 0xdf43fd28; */

您可以使用的最小单位是字节(char类型)。您可以使用位操作符来处理位。

至于整数字面值,您只能使用十进制(以10为基数)、八进制(以8为基数)或十六进制(以16为基数)数字。在C和c++中没有二进制(以2为基数)字面值。

八进制数前缀为0,十六进制数前缀为0x。十进制数没有前缀。

在c++ 0x中,你可以通过用户定义的文字来做你想做的事情。

这篇文章可能会有所帮助。

/* Helper macros */
#define HEX__(n) 0x##n##LU
#define B8__(x) ((x&0x0000000FLU)?1:0) \
+((x&0x000000F0LU)?2:0) \
+((x&0x00000F00LU)?4:0) \
+((x&0x0000F000LU)?8:0) \
+((x&0x000F0000LU)?16:0) \
+((x&0x00F00000LU)?32:0) \
+((x&0x0F000000LU)?64:0) \
+((x&0xF0000000LU)?128:0)

/* User macros */
#define B8(d) ((unsigned char)B8__(HEX__(d)))
#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \
+ B8(dlsb))
#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \
+ ((unsigned long)B8(db2)<<16) \
+ ((unsigned long)B8(db3)<<8) \
+ B8(dlsb))


#include <stdio.h>

int main(void)
{
    // 261, evaluated at compile-time
    unsigned const number = B16(00000001,00000101);

    printf("%d \n", number);
    return 0;
}

它的工作原理!(所有的功劳都归于汤姆·托夫斯。)

一些编译器(通常是微控制器的编译器)有一个特殊的功能,通过数字前面的前缀“0b…”来识别二进制数字,尽管大多数编译器(C/ c++标准)没有这样的功能,如果是这样的话,这里是我的替代解决方案:

#define B_0000    0
#define B_0001    1
#define B_0010    2
#define B_0011    3
#define B_0100    4
#define B_0101    5
#define B_0110    6
#define B_0111    7
#define B_1000    8
#define B_1001    9
#define B_1010    a
#define B_1011    b
#define B_1100    c
#define B_1101    d
#define B_1110    e
#define B_1111    f

#define _B2H(bits)    B_##bits
#define B2H(bits)    _B2H(bits)
#define _HEX(n)        0x##n
#define HEX(n)        _HEX(n)
#define _CCAT(a,b)    a##b
#define CCAT(a,b)   _CCAT(a,b)

#define BYTE(a,b)        HEX( CCAT(B2H(a),B2H(b)) )
#define WORD(a,b,c,d)    HEX( CCAT(CCAT(B2H(a),B2H(b)),CCAT(B2H(c),B2H(d))) )
#define DWORD(a,b,c,d,e,f,g,h)    HEX( CCAT(CCAT(CCAT(B2H(a),B2H(b)),CCAT(B2H(c),B2H(d))),CCAT(CCAT(B2H(e),B2H(f)),CCAT(B2H(g),B2H(h)))) )

// Using example
char b = BYTE(0100,0001); // Equivalent to b = 65; or b = 'A'; or b = 0x41;
unsigned int w = WORD(1101,1111,0100,0011); // Equivalent to w = 57155; or w = 0xdf43;
unsigned long int dw = DWORD(1101,1111,0100,0011,1111,1101,0010,1000); //Equivalent to dw = 3745774888; or dw = 0xdf43fd28;

缺点(不是什么大缺点):

二进制数必须按4 × 4分组; 二进制字面值只能是无符号整数;

优点:

Total preprocessor driven, not spending processor time in pointless operations (like "?.. :..", "<<", "+") to the executable program (it may be performed hundred of times in the final application); It works "mainly in C" compilers and C++ as well (template+enum solution works only in C++ compilers); It has only the limitation of "longness" for expressing "literal constant" values. There would have been earlyish longness limitation (usually 8 bits: 0-255) if one had expressed constant values by parsing resolve of "enum solution" (usually 255 = reach enum definition limit), differently, "literal constant" limitations, in the compiler allows greater numbers; Some other solutions demand exaggerated number of constant definitions (too many defines in my opinion) including long or several header files (in most cases not easily readable and understandable, and make the project become unnecessarily confused and extended, like that using "BOOST_BINARY()"); Simplicity of the solution: easily readable, understandable and adjustable for other cases (could be extended for grouping 8 by 8 too);