storing bits in char

Hi,

My friend wrote me this piece of code but he didn't explain it very well. I have 16 bits of information that are either 0 or 1, so he stored it in char[8] and he gets them back using:

int getWhite(char * whites, int led) {
      return (whites[led / 8] & (1 << (7 - (led % 8)) == 0) ? 0 : 1;
}

i have no idea how to interpret that or to see what's going on. i would appreciate it someone helped break it down for me.

thanks

have 16 bits of information that are either 0 or 1, so he stored it in char[8]

Storing 16 bits in a structure capable of storing 64 is wasteful.

whites[led / 8] & (1 << (7 - (led % 8)) == 0) ? 0 : 1

"led % 8" is the remainder when you divide the value "led" by 8.
Thus, if "led" is 10, led / 8 = 1, and led % 8 = 2
so "led / 8" addresses the second byte in your array, and "led % 8" gives you the position of the bit you want within that byte.

The rest just sets up a bitmask to extract that bit.

& (1 << (7 - (led % 8)) == 0) ? 0 : 1

"1 <<" means shift a single bit left by the number of places after the "<<" operator.
so, 1 << 1 = 10 (in binary) or decimal 2.
1 << 0 = 1
1 << 2 = 4

These allow you to isolate a single bit.

The "?" operator evaluate the expression to its left, and if true, returns the first of its operands (here "0"), otherwise it returns the rightmost (after the ":"), here "1".

Thus "(3 == (1 + 2) ? "A" : "B" "
would return the string "A".

i think i sort of get it. if whites[0] or whites[1] is empty, then it is 0 and because of the bitwise AND operator, it will return 0 and the whole thing is 0.

when it isn't empty, the first part of the compare is 1. then we go on to check the bit which is led % 8. but i don't get how shifting 1 left a certain number of places returns the bit value.

1<<0 = 1
1<<1 = 2
1<<2 = 4

1<<n is always bigger than 0. so doesn't that always return true as long as the whites[0] and whites[1] isn't empty? maybe i'm getting a bit confused here. if:

whites[0] = B10100000;

then whites[0] is not empty. and say we want the third bit (we count from the LSB on the right, yes?) so then

(1 << (7 - (led % 8))
is
(1 << (7 - 3)) = 1 << 4 = 16 > 0.

1 & 16 = 1, so the function would return 1 (i mean it shouldn't).

where have i gone wrong?

1<<n is always bigger than 0. so doesn't that always return true

You've missed out the bitwise logical AND operator "&".

If you've got a byte that contains a value, a simple test for odd or even is "value & 1".
This ANDs "value" with 1.
If the least significant bit of value is a "1", this expression will evaluate true, because "1 & 1 = 1".
"value" is thus odd.

If the least significant bit is a zero, "1 & 0 = 0", so "value" is even.

Thus "1 << x" isolates a single bit, and the "&" operation tests that bit.

Remember, whites [0] contains bits 0..7, whites [1] contains bits 8..15.

Incidentally, "led % 8" can also be written "led & 7" * - I'll leave you to figure out how :smiley:

  • For positive "led"