位移N位

时间:2009-08-14 01:18:40

标签: c# bit-manipulation bit-shift

关于位移的快速问题

我在HEX = new byte [] {0x56,0xAF};

中有一个值

,这是0101 0110 1010 1111

我想要前n位,例12

然后将剩余的4(16-12)转移到0000 0101 0110 1010(1386 dec)

我无法绕过它,让它可以扩展到n位。

谢谢!

5 个答案:

答案 0 :(得分:6)

前段时间我编写了这两个函数,第一个将一个字节[]向左移动一个指定的位数,第二个向右移动:

左移:

public byte[] ShiftLeft(byte[] value, int bitcount)
{
    byte[] temp = new byte[value.Length];
    if (bitcount >= 8)
    {
        Array.Copy(value, bitcount / 8, temp, 0, temp.Length - (bitcount / 8));
    }
    else
    {
        Array.Copy(value, temp, temp.Length);
    }
    if (bitcount % 8 != 0)
    {
        for (int i = 0; i < temp.Length; i++)
        {
            temp[i] <<= bitcount % 8;
            if (i < temp.Length - 1)
            {
                temp[i] |= (byte)(temp[i + 1] >> 8 - bitcount % 8);
            }
        }
    }
    return temp;
}

右移:

public byte[] ShiftRight(byte[] value, int bitcount)
{
    byte[] temp = new byte[value.Length];
    if (bitcount >= 8)
    {
        Array.Copy(value, 0, temp, bitcount / 8, temp.Length - (bitcount / 8));
    }
    else
    {
        Array.Copy(value, temp, temp.Length);
    }
    if (bitcount % 8 != 0)
    {
        for (int i = temp.Length - 1; i >= 0; i--)
        {
            temp[i] >>= bitcount % 8;
            if (i > 0)
            {
                temp[i] |= (byte)(temp[i - 1] << 8 - bitcount % 8);
            }
        }
    }
    return temp;
}

如果您需要进一步说明,请对此发表评论,然后我会编辑我的帖子以澄清......

答案 1 :(得分:1)

您可以使用BitArray,然后从右侧开始轻松将每个位复制到右侧。

http://msdn.microsoft.com/en-us/library/system.collections.bitarray_methods.aspx

答案 2 :(得分:1)

你想要类似......

var HEX = new byte[] {0x56, 0xAF};
var bits = new BitArray(HEX);
int bitstoShiftRight = 4;
for (int i = 0; i < bits.Length; i++)
{
   bits[i] = i < (bits.Length - bitstoShiftRight) ? bits[i + bitstoShiftRight] : false;
}
bits.CopyTo(HEX, 0);

答案 3 :(得分:0)

如果你有k个总位,并且你想要“第一个”(如同最重要的那样)n位,你可以简单地右移k-n次。最后一个k-n位将被删除,通过从末尾“下降”,并且第一个n将被移动到最不重要的一侧。

答案 4 :(得分:0)

使用类似C的表示法回答,假设bits_in_byte是在别处确定的字节中的位数:

int remove_bits_count= HEX.count*bits_in_byte - bits_to_keep;
int remove_bits_in_byte_count= remove_bits_count % bits_in_byte;

if (remove_bits_count > 0)
{
    for (int iteration= 0; iteration<min(HEX.count, (bits_to_keep + bits_in_byte - 1)/bits_in_byte); ++iteration)
    {
        int write_index= HEX.count - iteration - 1;
        int read_index_lo= write_index - remove_bits_count/bits_in_byte;

        if (read_index_lo>=0)
        {
            int read_index_hi= read_index_lo - (remove_bits_count + bits_in_byte - 1)/bits_in_byte;

            HEX[write_index]= 
                (HEX[read_index_lo] >> remove_bits_in_byte_count) | 
                (HEX[read_index_hi] << (bits_in_byte - remove_bits_in_byte_count));
        }
        else
        {
            HEX[write_index]= 0;
        }
    }
}

假设您正在覆盖原始数组,您基本上会将您写入的每个字节取出来,并计算出它将从其移位的字节。你从数组的末尾到前面,以确保你永远不会覆盖你需要阅读的数据。