A little something I would like to share.

I have recently ported Tom Torfs binary literal helper to my Arduino.
As you know binary numbers can be represented using one of the #defines in the core. E.g: byte b_6 = B00000110;

This code will allow you to now represent binary numbers up to 32 bits. I hope these macros might make someone's day a little easier.

uint8_t u_6 = B8(00000110);  //6

uint16_t u_AABB = B16( 10101010, 10111011 ); //43707

uint32_t u_AABBCCDD = B32( 10101010, 10111011, 11001100, 11011101 ); //2864434397

Here are the macros

/* 
    Binary constant generator macro 
    By Tom Torfs - donated to the public domain 
    All macro's evaluate to compile-time constants
*/ 

/* 
    HEX__(n)

        Turn a numeric literal into a hex constant ( avoids problems with leading zeroes ).
        8-bit constants max value 0x11111111, always fits in unsigned long 
*/ 

#define HEX__(n) 0x##n##LU 

/* 8-bit conversion function */ 
#define B8__( x ) ( ( x & 0x0000000FLU ) ? 1 : 0 ) + ( ( x & 0x000000F0LU ) ? 2 : 0 ) + ( ( x & 0x00000F00LU ) ? 4 : 0 ) + ( ( x & 0x0000F000LU ) ? 8 : 0 ) + ( ( x & 0x000F0000LU ) ? 16 : 0 ) + ( ( x & 0x00F00000LU ) ? 32 : 0 ) + ( ( x & 0x0F000000LU ) ? 64 : 0 ) + ( ( x & 0xF0000000LU ) ? 128 : 0 )

/* for upto 8-bit binary constants */ 
#define B8( d ) ( ( uint8_t ) B8__( HEX__( d ) ) ) 

/* for upto 16-bit binary constants, MSB first */ 
#define B16( dmsb, dlsb ) ( ( ( uint16_t ) B8( dmsb ) << 8 ) + B8( dlsb ) ) 

/* for upto 32-bit binary constants, MSB first */ 
#define B32( dmsb, db2, db3, dlsb ) ( ( ( uint32_t ) B8( dmsb ) << 24 ) + ( ( uint32_t ) B8( db2 ) << 16 ) + ( ( uint32_t ) B8( db3 ) << 8 ) + B8( dlsb ) )

Or you could use the "0b" notation.

Or you could use binary enough to realize why most with experience in bits use hex.

Or you could use binary enough to realize why most with experience in bits use hex.

hmmm, you mustn't have come across bit flags yet. They are somewhat difficult to construct large sequences using hex.

They are somewhat difficult to construct large sequences using hex.

It's a lot easier to spot a mistake in a quarter the number of characters, trust me!

Only if you have remembered hex bit patterns, binary 1 & 0 are a better choice for representing a set of true false values.

Only if you have remembered hex bit patterns,

They're in their fourth decade in my synapses - I think they're pretty well established.

I work registers up to 128 bits wide - spotting a flipped/transposed bit in the umpty third position is very much easier in hex.

While I don't want to dismiss the usefulness of those macros, I think investing a little brain effort in becoming fluent with HEX values is very worth the effort (if you pardon my English, that is... :stuck_out_tongue: )

It didn't take me a week to make the switch once I was shown. Remember that you're reading 4 bits per when you count for how long it takes and you're at least 4 times more likely to not lose track of places.

It's why I used the words "most with experience". Until you have the experience you can't imagine why.

Personally I find that once I start seeing numbers like this:

0b10000000100000011000000

Then my eyes start watering as I try to count the zeroes. It's like keying in the stupid transaction numbers they give you to pay bills. Something like:

Enter account:  45740000000001248

And I think "if I miscount those zeroes I've just paid someone else's bill".

As for bit flags, just use defines (or constants) and add them together.

eg.

const unsigned long LEFT   = 0x01;
const unsigned long RIGHT  = 0x02;
const unsigned long TOP    = 0x04;
const unsigned long BOTTOM = 0x08;

It is nice to have the Binary stuff, but having played with Hex on and off over 30+ years I can see the bits just as easy in Hex.

Back when I started there were those who were using Octal for everything, at the time I didn't see much use for it and many of them saw no use whatsoever for Hexidecimal. ( and yes, we had flame wars then too) Then when I worked on a Z80 assembler written in basic, Octal made a lot of sense as most of the opcodes were 2bits, 3bits 3bits for a total of 8 bits. Once you understood the Octal and the opcode tables you could program directly in machine code. different systems have their utility and once you get comfortable with them, its old hat...

I think using binary is useful with declaring things that pertain directly to hardware like the segment bits for a 7-seg display, especially if the relationship is not obvious, eg

// abcdefg.
 0b01000001
 0b00011000
 0b11000000
 0b00001000

where it's easy to set the 1s when defining and obvious at a later date what is what because the bits line up with the segments in the comment.

Otherwise I agree, HEX is more useful.


Rob

Having worked with Hex for so many years I can automatically see the binary much easier then the other way around, it just seems more concise and compact also.

Now I can't say the same thing for octal notation used by many of the minicomputer systems of the 70s and 80s. Splitting 16 bits word into two bytes using octal notation was one mental trick I could never seem to master, as that 'middle octal' character was split between the two halves of a word, madness I say. I blame the early software guys for that brain dead idea, a hardware guy would never give such a gift to the world. :wink:

Lefty

I agree
That is why the macros are broken into bytes.

I think using binary is useful with declaring things that pertain directly to hardware like the segment bits for a 7-seg display, especially if the relationship is not obvious, eg

Code:
// abcdefg.
0b01000001
0b00011000
0b11000000
0b00001000

where it's easy to set the 1s when defining and obvious at a later date what is what because the bits line up with the segments in the comment.

That is exactly what the macros are for.

Insert Quote
It didn't take me a week to make the switch once I was shown. Remember that you're reading 4 bits per when you count for how long it takes and you're at least 4 times more likely to not lose track of places.

Yes HEX is is great for making large numbers smaller, but not for working with individual binary, when you can clearly see your bits, there is no chance for a brain fart.

Have a look at some major operating systems, they use combining individual bit flags over setting some pre-calculated HEX value. Using one base for interpreting another is an easy way to add bugs to your code.

Having worked with Hex for so many years I can automatically see the binary much easier then the other way around, it just seems more concise and compact also.

Yes only when you have become comfortable with hex, binary is far simpler, just longer.

And if you all notice, they are helper macros, not intended for expressing every single number literal in your program, just ones that can benefit from having the bits exposed.

You can easily learn to do hex to binary conversions of any size in your head... It's much easier than decimal to binary conversion, because every 4 bits (every nybble) gets converted to exactly one hex value with no "carries".

For example, 0011 0011 0011 0011 (binary) gets converted to 3333 (hex). Every time you see 0011, that's a 3. Or with the Windows calculator in scientific mode, I can convert to 13107 (decimal), which is pretty useless when you're working with bits. :stuck_out_tongue:

You only have to memorize the 16 conversions between 0 and F:

0000 -> 0
0001 -> 1
0010 -> 2
0011 -> 3
0100 -> 4
0101 -> 5
0110 -> 6
0111 -> 7
1000 -> 8
1001 -> 9
1010 -> A
1011 -> B
1100 -> C
1101 -> D
1110 -> E
1111- > F

You already know zero and one, because they are the same in binary, hex, and decimal. Then, it's pretty easy to remember that 1111 is F, and not much harder to learn 0101 is 5, and that 1010 is A. It's also not to hard to remember 3 (0011) and 7 (0111).

Even if you can't remember, it's easy to figure out 4 (0100) and 8 (1000). Add one to 8 and you get 9 (1001). A (1010) is pretty easy, because A comes after 9 and it "looks like" 10". And, you can probably remember that E (1110) is one less than F.

So, that just leaves a few more values to memorize and and you're done!!!!

I understand your point,
however like I said, expressing big numbers in hex is useful and easier when converting from decimal. But when working with bit flags and such, you don't start with a decimal number, so taking your raw bits and converting them into a different notation not only obfuscates what you are intending to do, but introduces the need to mentally convert the value back to binary when ever you need to verify/update the declaration.

When dealing with lots of bits, I use hex but with Arduino and single bits I use bitRead(), bitSet() and bitClear().

Using hex is obfuscating? LOL, sure and so is using logical NOT or, gasp, shifts! Or "big words" (more than 6 letters) around stupid people.

When dealing with lots of bits, I use hex but with Arduino and single bits I use bitRead(), bitSet() and bitClear().

Using hex is obfuscating? LOL, sure and so is using logical NOT or, gasp, shifts! Or "big words" (more than 6 letters) around stupid people.

Before having a stab, try reading a post thoroughly.

I read hex, I see bits. Judas Priest, with a hex digit there's only 16 possibilities and half of those are 0-7.
As for intentions, LOL to the max, when you see the operations used then the meaning should be clear!

uint8_t u_6 = B8(00000110);  //6

uint16_t u_AABB = B16( 10101010, 10111011 ); //43707

uint32_t u_AABBCCDD = B32( 10101010, 10111011, 11001100, 11011101 ); //2864434397

Those are the examples, and they are supposed to be clearer than HEX? Are you hexophobic? Decocentric?

But when working with bit flags and such, you don't start with a decimal number

I have before. That's when I was told about hex. It's just numbers to me though.

I read hex, I see bits.

Congratulations, you must be proud. You are still missing the point.