你好关于位移的快速问题
我有一个十六进制值:new byte[] { 0x56, 0xAF };
这是0101 0110 1010 1111
我想要前 N 位,例如 12。
然后我必须右移最低 4 位 (16 - 12) 以获得0000 0101 0110 1010
(1386 dec)。
我无法绕开它并使其可扩展为 n 位。
你好关于位移的快速问题
我有一个十六进制值:new byte[] { 0x56, 0xAF };
这是0101 0110 1010 1111
我想要前 N 位,例如 12。
然后我必须右移最低 4 位 (16 - 12) 以获得0000 0101 0110 1010
(1386 dec)。
我无法绕开它并使其可扩展为 n 位。
前段时间我编写了这两个函数,第一个将 byte[] 向左移动指定数量的位,第二个向右移动:
左移:
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;
}
如果您需要进一步解释,请对此发表评论,然后我将编辑我的帖子以进行澄清...
你想要类似...
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);
您可以使用 BitArray,然后从右侧开始轻松地将每个位复制到右侧。
http://msdn.microsoft.com/en-us/library/system.collections.bitarray_methods.aspx
如果您有 k 个总位,并且您想要“第一个”(如最高有效位)n 位,您可以简单地右移 kn 次。最后 kn 位将被删除,通过某种“下降”结束,第一个 n 将被移动到最低有效侧。
使用类 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;
}
}
}
假设您要覆盖原始数组,您基本上会获取写入的每个字节,并找出它将从中获得移位位的字节。你从数组的末端走到前面,以确保你永远不会覆盖你需要读取的数据。