我需要处理一个二进制数。
我试着写:
const char x = 00010000;
但这并没有起作用。
我知道我可以使用与00010000值相同的十六进制数,但我想知道在c++中是否有用于二进制数的类型,如果没有,是否有其他解决方案?
我需要处理一个二进制数。
我试着写:
const char x = 00010000;
但这并没有起作用。
我知道我可以使用与00010000值相同的十六进制数,但我想知道在c++中是否有用于二进制数的类型,如果没有,是否有其他解决方案?
当前回答
你可以使用这个问题中的函数在c++中获得最多22位。下面是经过适当编辑的链接代码:
template< unsigned long long N >
struct binary
{
enum { value = (N % 8) + 2 * binary< N / 8 > :: value } ;
};
template<>
struct binary< 0 >
{
enum { value = 0 } ;
};
所以你可以这样做binary<0101011011>::value。
其他回答
二进制常数将在C23中标准化。在撰写本文时,最新的C2x标准草案的6.4.4.1/4中提到了拟议的符号:
[…二进制常数由前缀0b或0b后跟一组数字0或1组成。
基于其他一些答案,但这个将拒绝具有非法二进制字面值的程序。前导0是可选的。
template<bool> struct BinaryLiteralDigit;
template<> struct BinaryLiteralDigit<true> {
static bool const value = true;
};
template<unsigned long long int OCT, unsigned long long int HEX>
struct BinaryLiteral {
enum {
value = (BinaryLiteralDigit<(OCT%8 < 2)>::value && BinaryLiteralDigit<(HEX >= 0)>::value
? (OCT%8) + (BinaryLiteral<OCT/8, 0>::value << 1)
: -1)
};
};
template<>
struct BinaryLiteral<0, 0> {
enum {
value = 0
};
};
#define BINARY_LITERAL(n) BinaryLiteral<0##n##LU, 0x##n##LU>::value
例子:
#define B BINARY_LITERAL
#define COMPILE_ERRORS 0
int main (int argc, char ** argv) {
int _0s[] = { 0, B(0), B(00), B(000) };
int _1s[] = { 1, B(1), B(01), B(001) };
int _2s[] = { 2, B(10), B(010), B(0010) };
int _3s[] = { 3, B(11), B(011), B(0011) };
int _4s[] = { 4, B(100), B(0100), B(00100) };
int neg8s[] = { -8, -B(1000) };
#if COMPILE_ERRORS
int errors[] = { B(-1), B(2), B(9), B(1234567) };
#endif
return 0;
}
您可以使用的最小单位是字节(char类型)。您可以使用位操作符来处理位。
至于整数字面值,您只能使用十进制(以10为基数)、八进制(以8为基数)或十六进制(以16为基数)数字。在C和c++中没有二进制(以2为基数)字面值。
八进制数前缀为0,十六进制数前缀为0x。十进制数没有前缀。
在c++ 0x中,你可以通过用户定义的文字来做你想做的事情。
我扩展了@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; */
正如前面所回答的,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。