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

我试着写:

const char x = 00010000;

但这并没有起作用。

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


当前回答

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

/* 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;
}

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

其他回答

你可以尝试使用bool类型的数组:

bool i[8] = {0,0,1,1,0,1,0,1}

只需使用c++中的标准库:

#include <bitset>

你需要一个std::bitset类型的变量:

std::bitset<8ul> x;
x = std::bitset<8>(10);
for (int i = x.size() - 1; i >= 0; i--) {
      std::cout << x[i];
}

在本例中,我将10的二进制形式存储在x中。

8ul定义了位的大小,所以7ul意味着7位等等。

正如前面所回答的,C标准没有办法直接编写二进制数。不过,编译器也有扩展,显然c++ 14包含了二进制前缀0b。(请注意,这个答案最初发布于2010年。)

一种流行的解决方法是包含带有helper宏的头文件。一个简单的选择是生成一个包含所有8位模式宏定义的文件,例如:

#define B00000000 0
#define B00000001 1
#define B00000010 2
…

这导致只有256个#定义,如果需要大于8位的二进制常量,这些定义可以与移位和or组合,可能还可以使用辅助宏(例如BIN16(B00000001,B00001010))。(为每个16位(更不用说32位)值设置单个宏是不合理的。)

当然,这种语法的缺点是需要写入所有前导零,但这也可能使设置位标志和硬件寄存器内容等用途更加清晰。对于导致语法没有此属性的类函数宏,请参阅上面链接的bithacks.h。

我扩展了@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; */

我提出我的解决方案:

    #define B(x)                \
       ((((x) >>  0) & 0x01)    \
      | (((x) >>  2) & 0x02)    \
      | (((x) >>  4) & 0x04)    \
      | (((x) >>  6) & 0x08)    \
      | (((x) >>  8) & 0x10)    \
      | (((x) >> 10) & 0x20)    \
      | (((x) >> 12) & 0x40)    \
      | (((x) >> 14) & 0x80))

const uint8 font6[] = {
    B(00001110),    //[00]
    B(00010001),
    B(00000001),
    B(00000010),
    B(00000100),
    B(00000000),
    B(00000100),
    B(00000000),

我用这种方式定义了8位字体和图形,但也可以使用更宽的字体。宏B可以定义为生成0b格式,如果编译器支持的话。 操作:将二进制数解释为八进制,然后将位掩码并一起移位。中间值受到编译器可以处理的最大整数的限制,我猜64位应该可以。

它完全由编译器处理,不需要运行时代码。