我有一个byte[]字节数组,通常byteArray.Length = 1-3。
我需要将数组分解为位,取出一些位(例如5-17),并将这些位转换为Int32。
我尝试过这样做:
private static IEnumerable<bool> GetBitsStartingFromLSB(byte b)
{
for (int i = 0; i < 8; i++)
{
yield return (b % 2 != 0);
b = (byte)(b >> 1);
}
}
public static Int32 Bits2Int(ref byte[] source, int offset, int length)
{
List<bool> bools = source.SelectMany(GetBitsStartingFromLSB).ToList();
bools = bools.GetRange(offset, length);
bools.AddRange(Enumerable.Repeat(false, 32-length).ToList() );
int[] array = new int[1];
(new BitArray(bools.ToArray())).CopyTo(array, 0);
return array[0];
}
但是这种方法太慢了,而且我必须经常调用它。
如何更有效地完成这项工作呢?
非常感谢!现在我这样做:
public static byte[] GetPartOfByteArray( byte[] source, int offset, int length)
{
byte[] retBytes = new byte[length];
Buffer.BlockCopy(source, offset, retBytes, 0, length);
return retBytes;
}
public static Int32 Bits2Int(byte[] source, int offset, int length)
{
if (source.Length > 4)
{
source = GetPartOfByteArray(source, offset / 8, (source.Length - offset / 8 > 3 ? 4 : source.Length - offset / 8));
offset -= 8 * (offset / 8);
}
byte[] intBytes = new byte[4];
source.CopyTo(intBytes, 0);
Int32 full = BitConverter.ToInt32(intBytes);
Int32 mask = (1 << length) - 1;
return (full >> offset) & mask;
}
而且它非常快!
BitConverter
基本上没有任何用处;而且在我看来,在几乎任何其他情况下也是如此;实际上,BitConverter
上唯一真正有用的方法是.ToString()
,作为在单元测试中以十六进制方式编写的懒惰方法等,或许还有.IsLittleEndian
用于查询 CPU 的字节序。 - Marc Gravell