# What's going on in this binary operation?

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 01-14-2013
pyroknife
What's going on in this binary operation?
w1 &= 0xFFFFFFFE;

The book says it "For
example, to set the low-order bit of an int called w1 to 0, you can AND w1 with an int
consisting of all 1s except for a single 0 in the rightmost bit" and then referred to the above operation."

I don't understand what it's saying. Can someone explain?
• 01-14-2013
Salem
It's all about setting and clearing bits.

To set a bit, you 'or' it with 1
To clear a bit, you 'and' it with 0
To leave a bit unchanged when using 'or', use 0
To leave a bit unchanged when using 'and', use 1

> w1 &= 0xFFFFFFFE;
So in binary, we have
w1 &= 1111 1111 1111 1111 1111 1111 1111 1110;

Being an 'and' operation, it's leaving all the bits unchanged, except for the least significant bit, which will become zero.
• 01-14-2013
whiteflags
If you convert the hexadecimal number to binary it should make more sense.
1111 1111 1111 1111 1111 1111 1111 1110
Now AND that with another binary number.
• 01-14-2013
iMalc
I tend to write that sort of thing as:
Code:

`w1 &= ~1;`
• 01-14-2013
Click_here
This is going to annoy a few people (because some people just plain and simple hate this notation), but my favourite way is ~(1<<n) -> Probably because I first learnt C on the AVR microcontroller, and that is the method for writing to registers.

This clears the bit SPI2X in the register SPSR.
Code:

`SPSR &= ~(1 << SPI2X); /* No doubled clock frequency */`
Or you can see how a full register can be set up
Code:

```    /* 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);```
• 01-14-2013
Click_here
I should also add that if you look through the background files for the device, you will see these bits defined - For the ATmega128 in the example above, the bits were defined as...
Code:

```/* SPI Status Register - SPSR */ #define    SPIF        7 #define    WCOL        6 #define    SPI2X        0 /* SPI Control Register - SPCR */ #define    SPIE        7 #define    SPE          6 #define    DORD        5 #define    MSTR        4 #define    CPOL        3 #define    CPHA        2 #define    SPR1        1 #define    SPR0        0```
• 01-14-2013
pyroknife
Quote:

Originally Posted by Salem
It's all about setting and clearing bits.

To set a bit, you 'or' it with 1
To clear a bit, you 'and' it with 0
To leave a bit unchanged when using 'or', use 0
To leave a bit unchanged when using 'and', use 1

> w1 &= 0xFFFFFFFE;
So in binary, we have
w1 &= 1111 1111 1111 1111 1111 1111 1111 1110;

Being an 'and' operation, it's leaving all the bits unchanged, except for the least significant bit, which will become zero.

Thanks. What does the "0x" stand for in "0xFFFFFFFE" again?
Is it just some notation for hexidecimal?
• 01-14-2013
laserlight
Yes.
• 01-14-2013
pyroknife
Quote:

Originally Posted by laserlight
Yes.

Okay thanks.
and if an int is defined as w1=0525u, what does the 0 in the front and u in the end mean?

u, I think means unsigned, but I haven't seen what the 0 means.
• 01-14-2013
laserlight
Octal.
• 01-15-2013
Subsonics
Quote:

Originally Posted by Click_here
For the ATmega128 in the example above, the bits were defined as...

Makes you wonder why it was not defined as: (1<<7), (1<<6), (1<<5) etc. to begin with.
• 01-15-2013
Click_here
Quote:

Originally Posted by Subsonics
Makes you wonder why it was not defined as: (1<<7), (1<<6), (1<<5) etc. to begin with.

It's so that you can see the 0 or 1 and change it easily, whilst also seeing what bit in the register is being written to - See the example writing to SPCR and note that they are not all (1<<n).

I find that this is the best way, because I can easily see what is being set and cleared and refer directly to the data sheet. If they were already defined as (1<<n) and you wanted to clear the bit, you would have to omit it or come up with another name for an off definition.

But as I said earlier, most people hate this notation - I like it because it is a ANSI standard way of dealing with each bit (unlike microchip's use of anonomous bit fields within a union) and it is easy to see what is being set/cleared (unlike CCS where a description of what you want done is defined and you don't actually know what is being set cleared - This makes referring to the data sheet annoying).
• 01-15-2013
Subsonics
Quote:

Originally Posted by Click_here

It's so that you can see the 0 or 1 and change it easily, whilst also seeing what bit in the register is being written to - See the example writing to SPCR and note that they are not all (1<<n).

But as I said earlier, most people hate this notation - I like it because it is a ANSI standard way of dealing with each bit (unlike microchip's use of anonomous bit fields within a union) and it is easy to see what is being set/cleared (unlike CCS where a description of what you want done is defined and you don't actually know what is being set cleared - This makes referring to the data sheet annoying).

Yeah I guess it gives you a bit more information, but (0<<n) is the same as omitting the flag to begin with and most api's that I have seen use a mask that is already set to the destined bit, that's all.

It's not that I hate the notation just curious why they didn't choose to hide the details behind the interface, you could still clear the bit from the mask etc.
• 01-15-2013
Click_here
Quote:

but (0<<n) is the same as omitting the flag to begin with
I'd rather see it there, because the 0 doesn't always mean something is turned off and can be ignored - It could be a choice between two modes. And I like to see it commented on line by line, so that there are no surprises.

Quote:

just curious why they didn't choose to hide the details behind the interface
That they made "_BV(n)" for (1<<n) - And I'm sure someone would have made a clearbit(n) and setbit(n) macro and released it on avrfreaks.

But this goes back to what you like working with -> For me it's easier to change a 0 to 1 and comment then clearbit to setbit and comment

Open Question
What is your favourite notation for setting up registers?
• 01-16-2013
Subsonics
Quote:

Originally Posted by Click_here
I'd rather see it there, because the 0 doesn't always mean something is turned off and can be ignored - It could be a choice between two modes. And I like to see it commented on line by line, so that there are no surprises.

Well, (0<<n) is always 0 regardless of the value of n.

Quote:

Originally Posted by Click_here
That they made "_BV(n)" for (1<<n) - And I'm sure someone would have made a clearbit(n) and setbit(n) macro and released it on avrfreaks.

But this goes back to what you like working with -> For me it's easier to change a 0 to 1 and comment then clearbit to setbit and comment

Open Question
What is your favourite notation for setting up registers?

I was referring to the constants as "interface", not some utility function to set the bits. Much like say POSIX open() takes a combination of or:ed flags to set the mode without revealing the details of the specific bit position, meaning the constants can be used directly with out the shift operation.

Regarding your question, I don't have a "favorite" notation, I just got curious about the choice made in this api, because there is very often pros and cons to what ever choice is made. Reflecting over a particular choice can make you better when it comes to defining interfaces yourself.
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last