Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ binary constant/literal

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?

like image 377
Unknown Avatar asked Mar 31 '09 02:03

Unknown


People also ask

Does C have binary literals?

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.)

What is a binary literal?

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.

What is a binary constant?

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).

How do you write binary literals?

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.


2 Answers

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.

like image 62
Mark Ransom Avatar answered Oct 17 '22 20:10

Mark Ransom


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 :-)

like image 31
paxdiablo Avatar answered Oct 17 '22 19:10

paxdiablo