在代码中,我有时会看到人们以十六进制格式指定常量,如下所示:
const int has_nukes = 0x0001; const int has_bio_weapons = 0x0002; const int has_chem_weapons = 0x0004; // ... int arsenal = has_nukes | has_bio_weapons | has_chem_weapons; // all of them if(arsenal &= has_bio_weapons){ std::cout << "BIO!!" }
但是我在这里使用十六进制格式没有意义.有没有办法直接用二进制文件做?像这样的东西:
const int has_nukes = 0b00000000000000000000000000000001; const int has_bio_weapons = 0b00000000000000000000000000000010; const int has_chem_weapons = 0b00000000000000000000000000000100; // ...
我知道C/C++编译器不会编译它,但必须有一个解决方法吗?是否有可能在其他语言如Java?
在C++ 14中,您将能够使用以下语法的二进制文字:
0b010101010 /* more zeros and ones */
此功能在最新的已经实施clang
和gcc
.如果您使用-std=c++1y
选项运行这些编译器,则可以尝试使用它.
我使用位移操作符:
const int has_nukes = 1<<0; const int has_bio_weapons = 1<<1; const int has_chem_weapons = 1<<2; // ... int dangerous_mask = has_nukes | has_bio_weapons | has_chem_weapons; bool is_dangerous = (country->flags & dangerous_mask) == dangerous_mask;
它甚至比0的泛滥更好.
顺便说一句,下一个C++版本将支持用户定义的文字.它们已经包含在工作草案中.这允许那种东西(让我希望我没有太多的错误):
templateconstexpr int operator "" _b() { return conv2bin ::value; } int main() { int const v = 110110110_b; }
conv2bin
将是这样的模板:
templatestruct conv2bin; template struct conv2bin { static_assert(high == '0' || high == '1', "no bin num!"); static int const value = (high - '0') * (1 << sizeof...(digits)) + conv2bin ::value; }; template struct conv2bin { static_assert(high == '0' || high == '1', "no bin num!"); static int const value = (high - '0'); };
好吧,我们得到的是二进制文字,在编译时已经完全评估,因为上面的"constexpr".以上使用硬编码的int返回类型.我想甚至可以使它依赖于二进制字符串的长度.对于任何感兴趣的人,它都使用以下功能:
广义常数表达式.
Variadic模板.可在此处找到简要介绍
静态断言(static_assert)
用户定义的文字
实际上,当前的GCC trunk 已经实现了可变参数模板和静态断言.我们希望它能尽快支持其他两个.我认为C++ 1x将会震撼整个房子.
C++标准库是你的朋友:
#includeconst std::bitset <32> has_nukes( "00000000000000000000000000000001" );
如果你愿意,可以使用<<.
int hasNukes = 1; int hasBioWeapons = 1 << 1; int hasChemWeapons = 1 << 2;
自4.3以来,GCC支持二进制常量作为扩展.请参阅公告(请参阅"新语言和语言特定改进"部分).
这个讨论可能很有意思 ......可能一直存在,因为链接已经不幸了.它描述了一种类似于其他答案的基于模板的方法.
还有一个名为BOOST_BINARY的东西.
你想要的术语是二进制文字
Ruby使用您提供的语法.
另一种方法是定义辅助宏以便为您进行转换.我在http://bytes.com/groups/c/219656-literal-binary找到了以下代码
/* Binary constant generator macro * By Tom Torfs - donated to the public domain */ /* All macro's evaluate to compile-time constants */ /* *** helper macros *** */ /* turn a numeric literal into a hex constant * (avoids problems with leading zeroes) * 8-bit constants max value 0x11111111, always fits in unsigned long */ #define HEX_(n) 0x##n##LU /* 8-bit conversion function */ #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 *** / /* for upto 8-bit binary constants */ #define B8(d) ((unsigned char) B8_(HEX_(d))) /* for upto 16-bit binary constants, MSB first */ #define B16(dmsb, dlsb) (((unsigned short) B8(dmsb) << 8) \ | B8(dlsb)) /* for upto 32-bit binary constants, MSB first */ #define B32(dmsb, db2, db3, dlsb) (((unsigned long) B8(dmsb) << 24) \ | ((unsigned long) B8( db2) << 16) \ | ((unsigned long) B8( db3) << 8) \ | B8(dlsb)) /* Sample usage: * B8(01010101) = 85 * B16(10101010,01010101) = 43605 * B32(10000000,11111111,10101010,01010101) = 2164238933 */