|= and &=

Hi sorry, I’m new to the forum here. I just have a quick question about syntax, and I can’t seem to get good search results on it.

Could someone tell me what this code means?:

screen[column-1] &= ~(B1 << (row - 1));

Specifically, the “~”, and also the “&=” and also from a different section “|=”?

Thanks in advance

B1 would most likely equal “1”

Because C was designed to take the place of assembly language for most programming tasks, it needed to be able to support many operations that can be done in assembler language: This sort of argument is used to turn on/off bits.

To turn on a single bit it follows the following format:

(let’s stay that _byte is of value (binary) 0100 0010)
_byte |= (1 << 4); // which would equal (binary) 0001 0000

ie “1” shifted to the left 4 times:
0000 0001
0000 0010 (1)
0000 0100 (2)
0000 1000 (3)
0001 0000 (4)

the |= operator is a shortcut to saying _byte = _byte | (1 << 4);

Which would OR the 2 binary numbers together (bitwise)
0100 0010 OR
0001 0000 =
0101 0010

Now to turn one of these bits off, you would need to AND the bit in _byte with a ‘0’.

To do this, you choose a bit you want turned off…
(Let’s say) (1<<4) again (00010000)

First you need to make sure it is the only bit which is 0, and to do this you use the ‘~’ operand.
~(1<<4) = ~(0001 0000) = (1110 1111)

Now you need to AND _byte with this number and store it back in itself.

(Therefore)
_byte &= ~(1<<4)

(Therefore)
_byte = _byte & ~(1<<4) = _byte & 1110 1111

0101 0010 AND
1110 1111 =
0100 0010

Usually, the program doesn’t say “4”, it usually says something like “PIN5” or “BIT5”, and so what you see is “(1<<BIT5)”.

An actual example from some professional code related to the micro SD card:

/* initialize SPI with lowest frequency; max. 400kHz during identification mode of card */
    SPCR = (0 << SPIE)   | /* SPI Interrupt Enable */
                (1 << SPE)    | /* SPI Enable */
                (0 << DORD) | /* Data Order: MSB first */
                (1 << MSTR)  | /* Master mode */
                (0 << CPOL)  | /* Clock Polarity: SCK low when idle */
                (0 << CPHA)  | /* Clock Phase: sample on rising SCK edge */
                (1 << SPR1)  | /* Clock Frequency: f_OSC / 128 */
                (1 << SPR0);

In another file, SPR0 through to SPIE are defined as their bit number- The actual programmer than didn’t have to worry about what bit number SPR0 or SPR1 where to use them. Notice that the (0<<whatever) doesn’t actually do anything, it just tells the reader for the code what the bit is and why they are doing it (very easy to maintain).

If you are looking for more info on how these things are calculated, see http://www.codeproject.com/KB/cpp/bitbashing.aspx

:slight_smile:

Davak,

Those statements are using "bitwise" operators, that allow you to easily operate on individual bits in a variable.

& does an AND operation between the bits of the two operands. | does an OR operation between the bits of the two operands. ~ inverts all of the bits of its single operand: all of the 1's become 0's, and all of the 0's become 1's.

Regards,

-Mike

Okay, thanks very much, that helps alot. Also I almost always use "B1" and "B0" instead of "HIGH" and "LOW" and recommend doing so because it's shorter and you can also use "B1011" or whatever you need for larger variables and such. Thanks again, David Novak

The usual "Language Reference" page....

http://arduino.cc/en/Reference/HomePage

... is very good, but also bookmark the Extended Reference page...

http://arduino.cc/en/Reference/Extended

Among other things, you will find there a section called "Bitwise Operators" which might be of interest regarding |=, etc.

As for B0, B1 being shorter...

Another "solution" to that "problem" is to put....

#define lo LOW //no ; here
#define hi HIGH //no ; here

No, I don't do that myself. Yes, I always put the "//no ; here" on every #define line. The error messages arising when you put a semicolon in are often obscure, and I'm usually using copy/paste anyway.

... at the start of your code.

Another "solution" to that "problem" is to put....

or simply use 0 and 1 instead of LOW and HIGH. The value of LOW and HIGH couldn't change in a new version of arduino anyway as that would break too many programs.

Oh great! Thanks a lot everyone. Thanks for pointing out the extended reference page, I somehow missed the links to it on the main reference page.