我想知道如何在16字节数组(128位)中设置特定位。
例如......如果我想在数组中设置第9位,我希望:
{00,80,00,00,00,00,00,00,00,00,00,00,00,00,00,00}
如果我想设置第125位...
<00> 00,00 00,00,00,00,00,00,00,00,00,00,00,00,000}我已经研究过使用位移,但是对于如何使用由128位组成的数组进行位移而感到困惑。有没有办法打破这个大小的数组并以较小的字节块进行评估?任何帮助将不胜感激。
答案 0 :(得分:22)
选择特定位的过程包括两个步骤:
拾取字节很简单:您需要做的就是将位索引除以字节中的位数 - 即除以8:
int byteIndex = bitIndex / 8;
现在您知道要使用的字节,请计算您要访问的位。为此你需要计算除法的余数,如下所示:
int bitInByteIndex = bitIndex % 8;
有了这两个索引,就可以轻松访问该位:使用1 << bitInByteIndex
作为掩码,如下所示:
byte mask = (byte)(1 << bitInByteIndex);
bool isSet = (bytes[byteIndex] & mask) != 0;
// set to 1
bytes[byteIndex] |= mask;
// Set to zero
bytes[byteIndex] &= ~mask;
// Toggle
bytes[byteIndex] ^= mask;
答案 1 :(得分:13)
您可以使用BitArray:
byte[] bytearray = new byte[16];
var bitArray = new BitArray(bytearray);
bitArray.Set(8, true);
bitArray.CopyTo(bytearray, 0);
答案 2 :(得分:7)
直接来自字节数组,您最快的解决方案可能是使用BitArray。 - http://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx
E.g。这将是:
public void BitManimulation()
{
//Ill just use 2 bytes here for demonstration, get your 16 bytes here.
byte[] bytes = new[] { (byte)250, (byte)250 };
//Convert your bytes to a BitArray.
BitArray array = new BitArray(bytes);
array[3] = !array[3]; // Flip
array[4] = false; // 0
array[5] = true; // 1
//Convert back to bytes.
byte[] bytes2 = new byte[2];
array.CopyTo(bytes2,0);
Console.WriteLine(bytes2[0]);
Console.WriteLine(bytes2[1]);
}
现在这会带来性能损失。
所以作为替代方案,你有BitVector32需要你将4个字节的块转换为整数... - http://msdn.microsoft.com/en-us/library/system.collections.specialized.bitvector32.aspx
最后你可以进行位移,XOR等以产生所需的结果。既然@dasblinkenlight已经给那个病人留下了一个很好的答案,那就让你解释一下。^
以下是基于他的帖子的一些快速帮助方法:
public static class ByteArrayExt
{
public static byte[] SetBit(this byte[] self, int index, bool value)
{
int byteIndex = index / 8;
int bitIndex = index % 8;
byte mask = (byte)(1 << bitIndex);
self[byteIndex] = (byte)(value ? (self[byteIndex] | mask) : (self[byteIndex] & ~mask));
return self;
}
public static byte[] ToggleBit(this byte[] self, int index)
{
int byteIndex = index / 8;
int bitIndex = index % 8;
byte mask = (byte)(1 << bitIndex);
self[byteIndex] ^= mask;
return self;
}
public static bool GetBit(this byte[] self, int index)
{
int byteIndex = index / 8;
int bitIndex = index % 8;
byte mask = (byte)(1 << bitIndex);
return (self[byteIndex] & mask) != 0;
}
}
答案 3 :(得分:1)
将位数除以8会得到字节。以模8为模可以得到字节内的位数。
答案 4 :(得分:1)
首先,您需要找出您正在使用的字节。假设你有:
00000000 00000000 00000000 00000000 ...
你想要打开第10位,所以它需要变成这样:
00000000 01000000 00000000 00000000 ...
所以首先用8除法(向下舍入)来定位字节数(在这种情况下是字节编号1或第二个字节)。完成后,您可以使用按位运算符来设置所需的位,即
array[1] |= 0x40
我们在该字节的旧值和0x40(即01000000
)之间进行按位OR运算。如果旧值为00101101
,则array[1]
= (00101101 OR 01000000)
,即01101101
。
当然,在这种情况下,我一直在使用文字,所以你必须根据设置的位来改变它(例如,如果你在最后一位之前设置位,你想使用0x02
等等。
答案 5 :(得分:0)
您还可以使用lookUp,如下所示:
byte[] lookUp = { 1, 2, 4, 8, 16, 32, 64, 128 };
以下代码(考虑以字节为单位的反向位数)
int bytePosition = bitIndex / 8;
int bitInBytePosition = bitIndex % 8;
if (bitIndex < 8)
{
bitInBytePosition = bitIndex;
}
array[bytePosition] ^= lookUp[7 - bitInBytePosition];