Inserting binary values into C
9 July, 2010 - 11:53 — rapitaThis is an old C programmers trick for binary literals in C and is taken from a posting by Tom Torfs (http://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f?p...). It is particularly useful in a mixed C/Ada environment because Ada allows binary literals and you may wish to move one or more into C when doing optimisation or other development. The trick is to take a binary literal, pretend it is a hex value and then combine the hex nibbles into binary digits.
This particular version provides link time protection against passing in a non-binary value:
#define BINHEX( X ) ( \ (X & 0xEEEEEEEEuL) \ ? undefined( ) \ : ( ( ( (X * 0x1248uL) & 0xF000F000uL ) * 0x1001 ) >> 24 ) \ ) #define _0b( N ) ( BINHEX(0x##N##uL) )
Note that it works for at most 8 binary digits. To get wider values, just concatenate bytes, as in the following example:
const unsigned long val = (_0b(11111111) << 24)
| (_0b(00000000) << 16)
| (_0b(10101010) << 8)
| _0b(00111100);
Or, probably better, rewrite the _0b macro to take 4 bytes:
#define _0b( N3, N2, N1, N0 ) ( \
BINHEX(0x##N3##uL) << 24 \
| BINHEX(0x##N2##uL) << 16 \
| BINHEX(0x##N1##uL) << 8 \
| BINHEX(0x##N0##uL) \
)
so that you can just write:
const unsigned long val = _0b(11111111,00000000,10101010,00111100);
This compares very nicely with the Ada equivalent:
val : constant UInt32_Type := 2#11111111_00000000_10101010_00111100#;
- rapita's blog
- Login or register to post comments

Compiler extensions
It's great to have portable code, but it's also useful to know that many compilers (GCC for example) have extensions to include binary literals.
i = 0b101010;