C++ 二进制常量/文字
我正在使用一个众所周知的模板来允许二进制常量,
template< unsigned long long N >
struct binary
{
enum { value = (N % 10) + 2 * binary< N / 10 > :: value } ;
};
template<>
struct binary< 0 >
{
enum { value = 0 } ;
};
因此您可以执行类似“binary<101011011>::value”的操作。 不幸的是,无符号 long long 的长度限制为 20 位。
有人有更好的解决方案吗?
I'm using a well known template to allow binary constants
template< unsigned long long N >
struct binary
{
enum { value = (N % 10) + 2 * binary< N / 10 > :: value } ;
};
template<>
struct binary< 0 >
{
enum { value = 0 } ;
};
So you can do something like binary<101011011>::value. Unfortunately this has a limit of 20 digits for a unsigned long long.
Does anyone have a better solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
如果您的二进制值有一个前导零,这是否有效? 前导零使常数成为八进制而不是十进制。
这导致了一种从该解决方案中挤出更多数字的方法 - 始终以零开始二进制常量! 然后将模板中的 10 替换为 8。
Does this work if you have a leading zero on your binary value? A leading zero makes the constant octal rather than decimal.
Which leads to a way to squeeze a couple more digits out of this solution - always start your binary constant with a zero! Then replace the 10's in your template with 8's.
我一直使用的方法,虽然不如你的那么优雅:
1/只使用十六进制。 一段时间后,您就会知道哪些十六进制数字代表哪些位模式。
2/ 使用常量并对它们进行“或”或“加”操作。 例如(可能需要对位模式进行限定符以使它们成为无符号或长整型):
3/ 如果性能并不重要且可读性很重要,则可以在运行时使用诸如“x = fromBin(”101011011 “);”。
4/ 作为一个偷偷摸摸的解决方案,您可以编写一个预处理器来遍历 *.cppme 文件并通过将所有“0b101011011”类型字符串替换为其等效的“0x15b”字符串来创建 *.cpp 文件。 我不会轻易这样做,因为您可能需要担心各种棘手的语法组合。 但它允许您按照自己的意愿编写字符串,而不必担心编译器的变化无常,并且您可以通过仔细编码来限制语法的复杂性。
当然,下一步是修补 GCC 以识别“0b”常量,但这可能有点矫枉过正:-)
The approaches I've always used, though not as elegant as yours:
1/ Just use hex. After a while, you just get to know which hex digits represent which bit patterns.
2/ Use constants and OR or ADD them. For example (may need qualifiers on the bit patterns to make them unsigned or long):
3/ If performance isn't critical and readability is important, you can just do it at runtime with a function such as "x = fromBin("101011011");".
4/ As a sneaky solution, you could write a pre-pre-processor that goes through your *.cppme files and creates the *.cpp ones by replacing all "0b101011011"-type strings with their equivalent "0x15b" strings). I wouldn't do this lightly since there's all sorts of tricky combinations of syntax you may have to worry about. But it would allow you to write your string as you want to without having to worry about the vagaries of the compiler, and you could limit the syntax trickiness by careful coding.
Of course, the next step after that would be patching GCC to recognize "0b" constants but that may be an overkill :-)
C++0x 有 用户定义的文字,可用于实现您正在谈论的内容。
不然我不知道如何改进这个模板。
C++0x has user-defined literals, which could be used to implement what you're talking about.
Otherwise, I don't know how to improve this template.
允许:
Bin::O::I::I::O::O::value
更加详细,但没有限制(当然,直到达到 unsigned int 的大小)。
Allowing:
Bin::O::I::I::O::O::value
much more verbose, but no limits (until you hit the size of an unsigned int of course).
您可以添加更多非类型模板参数来“模拟”其他位:
您可以像以前一样使用它,例如:
但您也可以使用以下等效形式:
基本上,额外的参数为您提供了另外 20 位可供使用。 如果需要,您可以添加更多参数。
因为第二个数字的位值用于计算第一个数字需要向左移动多远,所以第二个数字必须以 1 开头。(无论如何,这是必需的,因为以 0 开头会导致被解释为八进制数的数字。)
You can add more non-type template parameters to "simulate" additional bits:
You can use this as before, e.g.:
But you can also use the following equivalent forms:
Basically, the extra parameter gives you another 20 bits to play with. You could add even more parameters if necessary.
Because the place value of the second number is used to figure out how far to the left the first number needs to be shifted, the second number must begin with a 1. (This is required anyway, since starting it with a 0 would cause the number to be interpreted as an octal number.)
从技术上讲,它不是 C 也不是 C++,它是 GCC 特定的扩展,但 GCC 允许 二进制常量如此处所示:
希望有所帮助。 一些 Intel 编译器(我相信还有其他编译器)实现了一些 GNU 扩展。 也许你很幸运。
Technically it is not C nor C++, it is a GCC specific extension, but GCC allows binary constants as seen here:
Hope that helps. Some Intel compilers and I am sure others, implement some of the GNU extensions. Maybe you are lucky.
一个简单的 #define 效果很好:
不是我的发明,我很久以前在论坛上看到它。
A simple #define works very well:
Not my invention, I saw it on a forum a long time ago.