Bit shifting N bits

限于喜欢 提交于 2019-11-28 06:34:40

问题


Hello quick question regarding bit shifting

I have a value in HEX = new byte[] { 0x56, 0xAF };

which is 0101 0110 1010 1111

i want to the first n bits, example 12

then shift off the remaining 4 (16-12) to get 0000 0101 0110 1010 (1386 dec)

i cant wrap my head around it and make it scalable for n bits.

Thanks!


回答1:


Sometime ago i coded these two functions, the first one shifts an byte[] a specified amount of bits to the left, the second does the same to the right:

Left Shift:

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

Right Shift:

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

If you need further explanation please comment on this, i will then edit my post for clarification...




回答2:


You can use a BitArray and then easily copy each bit to the right, starting from the right.

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




回答3:


you want something like...

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



回答4:


If you have k total bits, and you want the "first" (as in most significant) n bits, you can simply right shift k-n times. The last k-n bits will be removed, by sort of "falling" off the end, and the first n will be moved to the least significant side.




回答5:


Answering using C-like notation, assuming bits_in_byte is the number of bits in a byte determined elsewhere:

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

Assuming you are overwriting the original array, you basically take every byte you write to and figure out the bytes that it would get its shifted bits from. You go from the end of the array to the front to ensure you never overwrite data you will need to read.



来源:https://stackoverflow.com/questions/1275572/bit-shifting-n-bits

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!