Bitwise operations

hi all

i am having trouble with a problem which requires me to set a number to the bottom 4 bits and use the top four bits to count the number of iterations for a traffic light eg.

1000 = red 0110 = yellow 0001 = green

and a counter will be used for the interations eg.

10000000 red start off
00011000 green light 1 iteration
01100100 yellow L 2 its
10001100 red lights 3 its


i have tried doing

int counter = counter & 240:
counter = counter | (number set for lights eg 1 6 8);

but this just gives
10000011
00010011
01100011

thanks in advance
1
2
3
4
upper_nibble = (byte & 0xF0) >> 4
lower_nibble = byte & 0x0F
//...
reconstruct = (upper_nibble << 4) | lower_nibble


I don't understand your examples
Last edited on
Bitwise operations are always a little tricky to make sense of at first.

To SET some bits, you can either:

  • clear them using bitwise AND
  • set them using bitwise OR

To GET some bits, you need to SHIFT and clear.


Specifically, your object is combining two integers.

1
2
  unsigned counter;  // 4 bits of data CCCC
  unsigned light_id; // 4 bits of data LLLL 

Put them together to get an 8-bit integer.

 
  unsigned counter_and_light_id;  // 4 MSB = counter, 4 LSB = light id: CCCC LLLL 

CLEAR operations:

  • Clear the counter:  counter_and_light_id &= 0x0F; 
  • Clear the light id: counter_and_light_id &= 0xF0;

So, 0010 1000 (counter = 3, light id = green light) AND 0000 1111 becomes 0000 1000 (counter = 0, light id = green light).

Likewise, 0010 1000 AND 1111 0000 becomes 0010 0000 (counter = 3, light id = red start off).

Once you have cleared something, you can SET it:

  • Set the counter: counter_and_light_id |= 5 << 4;
  • Set the light id: counter_and_light_id |= GREEN_LIGHT;

GET operations:

  • Get the counter: counter_and_light_id >> 4 (0010 1000 >> 4 → 0000 0010)
  • Get the light id: counter_and_light_id & 0x0F (0010 1000 AND 0000 1111 → 0000 1000)

Hopefully that makes sense.

To make life easy, you should make yourself some functions to split and combine the two values:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
unsigned get_counter( unsigned counter_and_light_id )
{
  return counter_and_light_id >> 4;
}

unsigned get_light_id( unsigned counter_and_light_id )
{
  return counter_and_light_id & 0x0F;
}

unsigned combine_counter_and_light_id( unsigned counter, unsigned light_id )
{
  return (counter << 4) | (light_id);
}

This becomes easy to use:

1
2
3
4
  counter_and_light_id = combine_counter_and_light_id(
    get_counter ( counter_and_light_id ) + 1,
    get_light_id( counter_and_light_id )
  );


(As an added bonus, to simply increment the counter, just add n << 4 to it:

1
2
3
4
5
unsigned increment_counter( unsigned counter_and_light_id, unsigned n = 1 )
{
  counter_and_light_id += n << 4; // increment the counter
  return counter_and_light_id & 0xF0; // make sure the counter value never exceeds 4 bits
}
 
counter_and_light_id = increment_counter( counter_and_light_id );

Hope this helps.
i dont undert stand how to implement this into my program as counter is given thru a for loop

trafficLight tL;
OUSB ousb;
int cycleNum = 0, counter = 0, OUSBVal = 0;
char parameter = 0;

if (argc == 3)
{
parameter = toupper(argv[1][0]);
if (argv[1][0] == 'R')
tL.redOn();
else if (argv[1][0] == 'G')
tL.greenOn();
else if (argv[1][0] == 'Y')
tL.yellowOn();
else
return 0;
tL.setLight();
int x;
cycleNum = atoi(argv[2]);

if (cycleNum >= 0 && cycleNum <= 15)
{
while (counter < cycleNum)
{
tL.changeLight();
/* ousb.writeportb(tL.q);*/
counter++;



}



where tL.g is 1 6 or 8 (traffic light value)

i tried using this
counter << 4;
counter = counter | tL.q;
cout << counter << endl;

but it didnt workl
combined = (counter << 4) | tL.q;

gotta pay attention. Good luck!
Topic archived. No new replies allowed.