2

I work with registers a bit, and data sheets that turn everything into bit indices. Luckily, I'm using GCC, which has the binary literal extension syntax so that i can do things like

register |= 0b01000010;

The other option is of course to just use hexadecimal format

register |= 0x42;

Despite having worked with hexadecimal numbers a bit over time, I still find binary format better for this kind of bit banging. I still decompose the 4 and 2 nibbles into their 0100 and 0010 patterns. So I think the binary format visualizes better. The problem with the binary format though, is that it's hard to find the boundaries. Using hexadecimal format, the nibbles separate nicely and so you can "index" bits safer sometimes. In other words, in the top I have to worry I didn't add or omit an extra 0 and end up with bit 7 on instead of 6.

Has a technique/trick been developed to have their cake and eat it too? When you have two string constants adjacent in C

"Hello " "World"

The compiler is smart enough to just mash them together into one literal. It would be nice if there was a way to do something similar with these binary numbers, e.g.,

0b0100 0010

I could do something weird with macros, perhaps

#define _(a, b) (((a) << 4) | (b))

and then be able to do

_(0b0100,0b0010)

but that's honestly worse, and limited to a pair of nibbles. Is there something clever and nice?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Travis Griggs
  • 21,522
  • 19
  • 91
  • 167
  • Use `(1 << 6) | (1 << 1)`... –  Dec 08 '12 at 05:34
  • 1
    FWIW, [C++14 has digit separators](https://en.cppreference.com/w/cpp/language/integer_literal), i.e. when compiling with `g++` instead of `gcc` you could write your constant like this: `0b0100'0010` I'm surprised that GCC hasn't already introduced this feature as GNU C extension. – maxschlepzig Feb 09 '20 at 13:24

1 Answers1

3

In C, you're limited to specifying integer constants in decimal, octal, and hexadecimal. Or combine groups of shifted constants (per H2CO3's comment below your question). If it's important enough to you, you could specify your contants as quoted string constants and call a function (of your own writing) to convert that & return its integer value. Anywhere you want to specify such a constant, just call your function in its place... int i = b("0100 1101 0011 1100"); ....Or use C++.... See Binary literals? and Can I use a binary literal in C or C++?

If you go with writing your own string constant converter, you can make it ignore non-[0,1] digits, so you can group the bits in any fashion depending on what you're specifying.

Community
  • 1
  • 1
phonetagger
  • 7,701
  • 3
  • 31
  • 55
  • 1
    I like the idea of that function. Make it `static inline` though, so it can be optimized away at compile-time (knowing what kind of optimizations GCC does, it will probably be replaced by the constant itself...) –  Dec 08 '12 at 07:57
  • 1
    @H2CO3 - I think such a function would be too complex to be optimized away. If he uses it often enough, and if his processor has an instruction cache, you wouldn't want it inlined anyway. There was a day when inlining made a whole lot of sense. The advent of instruction caches changes the game enough that now it only makes sense to inline truly trivial functions; i.e. ones that take on the order of the same number of instructions that would be involved in setting up & making a function call. If you inline longer functions & they're called repeatedly, your cache hit ratio suffers. – phonetagger Dec 08 '12 at 08:15
  • Wrong - [it just got optimized away.](http://stackoverflow.com/questions/15114140/writing-binary-number-system-in-c-code/15114188#15114188) –  Jun 08 '13 at 18:48
  • @H2CO3 - Ref. my comments under your answer in that question. Summary: It is indeed 'neat' that clang can optimize that function (with a loop!) down to a single constant. In my testing, GCC isn't able to do that, at least not in version 4.7.2. With -O3, GCC 4.7.2 merely inlines it. And if your printf() call is replaced with `printf("%lld 0x%llx\n", B(001100101), B(001100101));`, it inlines it twice... with two completely different generated forms of the assembly. – phonetagger Jun 10 '13 at 16:24