移位。这段代码中发生了什么?

时间:2012-07-28 13:52:50

标签: c# arrays boolean bit-manipulation bit-shift

我努力了,但我似乎无法理解这段代码中发生了什么。谁能请一些亮点?

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)));
            }
        }
    }

}

我没有得到有位操作的部分(三条线)。据我所知,在第一个中,它的ANDing位数组的值来查找该位是否打开。在第二个中,ORing和第三个ANDingNOT,是正确的我认为在这三行中发生了什么?

这件事真的伤害了我的大脑1 << (bitPos % 8)ANDingORingANDingNOT的关系是什么?我所知道的是,你可以向左或右对某事物的价值(或其他,我对此并不十分清楚。)那么这是做什么的?是转移1还是什么?

有人可以解释一下吗?

编辑:编辑完整代码...

2 个答案:

答案 0 :(得分:2)

Ok看起来像是一个私有字段,其中包含字节(m_byteArray),这从bytearray中获取一点(我假设bytearray是连续的,并且这会尝试从某个位置获取位 - 例如想象有3个字节,位置13从字节2得到第5位

编辑:总结一下

图像我们在字节数组中有3个字节

00101011 00101010 01000010

如果我们想要第13位,我们会将'12'传递给索引器重要提示!!

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

我们去

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

所以我们有第二个字节(在索引1处)

00101010
----^

现在我们去

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

相当于

00101010 & 00000001 << 4

哪个是

00101010 & 00001000

所以这掩盖了

1 & 1

返回1:)

对于最终为

的面具
1 & 0

逻辑上返回0

答案 1 :(得分:1)

该行:

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

返回是否设置了字节数组中的第n位。

bitPos / 8

找到索引位所在的字节,

1 << (bitPos % 8))

为相关字节创建一个位掩码。

例如,如果要查找是否设置了第10位,bitPos将为9。 bitPos / 8 = 1,因此关联的位在数组的第二个字节中。 bitPos % 8 = 1,因此表达式(1&lt;(bitPos%8))创建00000010的位掩码。如果设置了第二位,则将此掩码应用于byteArray[1]将返回1,否则返回0.

除了

之外,setter的逻辑类似
m_byteArray[bitPos / 8] | (1 << (bitPos % 8))

将该位设置在相关位置,而

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

将清除它。