C++ 二进制文字?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/537303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Binary literals?
提问by Frank
In code, I sometimes see people specify constants in hex format like this:
在代码中,我有时会看到人们以十六进制格式指定常量,如下所示:
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!!"
}
But it doesn't make sense to me to use the hex format here. Is there a way to do it directly in binary? Something like this:
但是在这里使用十六进制格式对我来说没有意义。有没有办法直接用二进制来做?像这样的东西:
const int has_nukes = 0b00000000000000000000000000000001;
const int has_bio_weapons = 0b00000000000000000000000000000010;
const int has_chem_weapons = 0b00000000000000000000000000000100;
// ...
I know the C/C++ compilers won't compile this, but there must be a workaround? Is it possible in other languages like Java?
我知道 C/C++ 编译器不会编译这个,但必须有一个解决方法?是否可以在其他语言(如 Java)中使用?
回答by sasha.sochka
In C++14 you will be able to use binary literals with the following syntax:
在 C++14 中,您将能够使用具有以下语法的二进制文字:
0b010101010 /* more zeros and ones */
This feature is already implemented in the latest clang
and gcc
. You can try it if you run those compilers with -std=c++1y
option.
此功能已在最新版本clang
和gcc
. 如果您使用-std=c++1y
选项运行这些编译器,您可以尝试一下。
回答by Tometzky
I'd use a bit shift operator:
我会使用位移运算符:
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;
It is even better than flood of 0's.
它甚至比 0 的泛滥还要好。
回答by Johannes Schaub - litb
By the way, the next C++ version will support user defined literals. They are already included into the working draft. This allows that sort of stuff (let's hope i don't have too many errors in it):
顺便说一句,下一个 C++ 版本将支持用户定义的文字。它们已经包含在工作草案中。这允许那种东西(让我们希望我没有太多错误):
template<char... digits>
constexpr int operator "" _b() {
return conv2bin<digits...>::value;
}
int main() {
int const v = 110110110_b;
}
conv2bin
would be a template like this:
conv2bin
将是这样的模板:
template<char... digits>
struct conv2bin;
template<char high, char... digits>
struct conv2bin<high, digits...> {
static_assert(high == '0' || high == '1', "no bin num!");
static int const value = (high - '0') * (1 << sizeof...(digits)) +
conv2bin<digits...>::value;
};
template<char high>
struct conv2bin<high> {
static_assert(high == '0' || high == '1', "no bin num!");
static int const value = (high - '0');
};
Well, what we get are binary literals that evaluate fully at compile time already, because of the "constexpr" above. The above uses a hard-coded int return type. I think one could even make it depend on the length of the binary string. It's using the following features, for anyone interested:
好吧,由于上面的“constexpr”,我们得到的是在编译时已经完全评估的二进制文字。上面使用了硬编码的 int 返回类型。我认为甚至可以让它取决于二进制字符串的长度。它使用以下功能,对于任何感兴趣的人:
- Generalized Constant Expressions.
- Variadic Templates. A brief introduction can be found here
- Static Assertions (static_assert)
- User defined Literals
Actually, current GCC trunk alreadyimplements variadic templates and static assertions. Let's hope it will support the other two soon. I think C++1x will rock the house.
实际上,当前的 GCC 主干已经实现了可变参数模板和静态断言。让我们希望它能很快支持另外两个。我认为 C++1x 会震撼整个房子。
回答by Johannes Schaub - litb
The C++ Standard Library is your friend:
C++ 标准库是您的朋友:
#include <bitset>
const std::bitset <32> has_nukes( "00000000000000000000000000000001" );
回答by Jon B
You can use << if you like.
如果您愿意,可以使用 << 。
int hasNukes = 1;
int hasBioWeapons = 1 << 1;
int hasChemWeapons = 1 << 2;
回答by bluebrother
GCC supports binary constants as an extension since 4.3. See the announcement(look at the section "New Languages and Language specific improvements").
GCC 从 4.3 开始支持二进制常量作为扩展。请参阅公告(查看“新语言和语言特定改进”部分)。
回答by Anonymous
This discussionmay be interesting... Might have been, as the link is dead unfortunately. It described a template based approach similar to other answers here.
这个讨论可能很有趣……可能很有趣,因为不幸的是链接已经死了。它描述了一种基于模板的方法,类似于此处的其他答案。
And also there is a thing called BOOST_BINARY.
还有一种叫做BOOST_BINARY的东西。
回答by Mark Pim
The term you want is binary literals
你想要的术语是二进制文字
Ruby has themwith the syntax you give.
Ruby 有你提供的语法。
One alternative is to define helper macros to convert for you. I found the following code at http://bytes.com/groups/c/219656-literal-binary
一种替代方法是定义要为您转换的辅助宏。我在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
*/
回答by Motti
The next version of C++, C++0x, will introduce user defined literals. I'm not sure if binary numbers will be part of the standard but at the worst you'll be able to enable it yourself:
C++ 的下一个版本 C++0x 将引入用户定义的文字。我不确定二进制数是否会成为标准的一部分,但最坏的情况是您可以自己启用它:
int operator "" _B(int i);
assert( 1010_B == 10);
回答by Darron
I write binary literals like this:
我这样写二进制文字:
const int has_nukes = 0x0001;
const int has_bio_weapons = 0x0002;
const int has_chem_weapons = 0x0004;
It's more compact than your suggested notation, and easier to read. For example:
它比您建议的符号更紧凑,更易于阅读。例如:
const int upper_bit = 0b0001000000000000000;
versus:
相对:
const int upper_bit = 0x04000;
Did you notice that the binary version wasn't an even multiple of 4 bits? Did you think it was 0x10000?
您是否注意到二进制版本不是 4 位的偶数倍?你以为是0x10000吗?
With a little practice hex or octal are easier for a human than binary. And, in my opinion, easier to read that using shift operators. But I'll concede that my years of assembly language work may bias me on that point.
稍加练习,十六进制或八进制对人类来说比二进制更容易。而且,在我看来,使用移位运算符更容易阅读。但我承认,我多年的汇编语言工作可能会在这一点上产生偏见。