1

I've tried really hard, but I can't seem to understand what's going on in this code. Can anyone please shed some light?

public class BitArrary
{
    private Byte[] m_byteArray;
    private Int32 m_numBits;


    public BitArrary(Int32 numBits)
    {
        if (numBits <= 0)
            throw new ArgumentOutOfRangeException("Must be greater then 0");

        m_numBits = numBits;
        m_byteArray = new Byte[(numBits + 7) / 8];
    }

    public Boolean this[Int32 bitPos]
    {
        get
        {
            if ((bitPos < 0) || (bitPos >= m_numBits))
            {
                throw new ArgumentOutOfRangeException("bitPos");
            }
            else
            {
                return (m_byteArray[bitPos / 8] & (1 << (bitPos % 8))) != 0;
            }
        }
        set
        {
            if ((bitPos < 0) || (bitPos > m_numBits))
                throw new ArgumentOutOfRangeException("bitPos");
            if (value)
            {
                m_byteArray[bitPos / 8] = (Byte)(m_byteArray[bitPos / 8] | (1 << (bitPos % 8)));
            }
            else
            {
                m_byteArray[bitPos / 8] = (Byte)(m_byteArray[bitPos / 8] & ~(1 << (bitPos % 8)));
            }
        }
    }

}

I don't get the parts (the three lines) where there is operation on bits. As far as I get it, in first one, its ANDing the value of bit array to find if that bit is on. In second one, its ORing, and in the third one ANDing with NOT, is that about right what I think is happening in these three lines?

Whats really hurting my brain in what is this doing 1 << (bitPos % 8)? And what does ANDing, ORing or ANDing with NOT of it, is going to do? What I know is that you can left or right shit a value of something (or other, I am not really clear on this.) So what is this doing? is it shift 1 or what?

Can anyone please explain?

EDIT : Edited for full code...

Razort4x
  • 3,296
  • 10
  • 50
  • 88
  • Looks like an indexed property to return the bits of a byte, returns true/false for each bits postion (set/unset respectively), I will post an answer with the detail :) – Charleh Jul 28 '12 at 13:54
  • See this post:[link](http://stackoverflow.com/questions/3883384/practical-applications-of-bitwise-operations) – Sinthia V Jul 28 '12 at 14:21

2 Answers2

2

Ok looks like the is a private field which contains the bytes (m_byteArray) and this gets a bit from the bytearray (I'm assuming that the bytearray is contiguous and this attempts to get the bits from a certain position - e.g. imagine there are 3 bytes, position 13 would get bit 5 from byte 2)

Edit: To summarise better

Image we have 3 bytes in the byte array

00101011 00101010 01000010

If we want bit 13 we would pass '12' to the indexer IMPORTANT TO REMEMBER!!

00101011 00101010 01000010
-------------^
(Remember it's 0 based)

We go

m_byteArray[12 / 8] (12 / 8 = 1 so we know we want byte number two at index 1 - byte array is also zero based!)

So we have the second byte (at index 1)

00101010
----^

Now we go

00101010 & (1 << (12 % 8))

Which is equivalent to

00101010 & 00000001 << 4

Which is

00101010 & 00001000

So this masks off to

1 & 1

Which returns 1 :)

For masks that end up as

1 & 0

Logically that returns 0

Charleh
  • 13,749
  • 3
  • 37
  • 57
  • I've updated the question to include the full code.. Though really thanks for such a nice explanation.. :) – Razort4x Jul 28 '12 at 14:09
  • Sorry I think it was a bit confusing first time round, I've clarified it by putting a step by step of the bytes – Charleh Jul 28 '12 at 14:16
1

The line:

return (m_byteArray[bitPos / 8] & (1 << (bitPos % 8))) != 0;

returns whether the nth bit in a byte array is set.

bitPos / 8

finds the byte in which the indexed bit is in, and

1 << (bitPos % 8))

creates a bitmask for the associated byte.

As an example, if you wanted to find whether the 10th bit was set, bitPos would be 9. bitPos / 8 = 1, so the associated bit is in the second byte within the array. bitPos % 8 = 1, so the expression (1 << (bitPos % 8)) creates a bitmask of 00000010. Applying this mask to byteArray[1] will return 1 if the second bit is set, or 0 otherwise.

The logic for the setters is similar, except that

m_byteArray[bitPos / 8] | (1 << (bitPos % 8))

will set the bit in the associated position, while

(m_byteArray[bitPos / 8] & ~(1 << (bitPos % 8))

will clear it.

Lee
  • 142,018
  • 20
  • 234
  • 287