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?
Binary integer literals (0b…) are supported in the C++ language but not in the C language. IAR Systems has added a compiler extension to support binary integer literals in C source code. (Legacy versions of the compiler do not support binary integer literals.)
A binary literal is a number that is represented in 0s and 1s (binary digits). Java allows you to express integral types (byte, short, int, and long) in a binary number system. To specify a binary literal, add the prefix 0b or 0B to the integral value.
Integer constants can be written as binary constants, consisting of a sequence of ' 0 ' and ' 1 ' digits, prefixed by ' 0b ' or ' 0B '. This is particularly useful in environments that operate a lot on the bit level (like microcontrollers).
Binary literals can be written in one of the following formats: b'value' , B'value' or 0bvalue , where value is a string composed by 0 and 1 digits. Binary literals are interpreted as binary strings, and are convenient to represent VARBINARY, BINARY or BIT values.
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.
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):
#define b0 0x00000001
#define b1 0x00000002
: : :
#define b31 0x80000000
unsigned long x = b2 | b7
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 :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With