【发布时间】:2020-12-26 12:43:24
【问题描述】:
我有byte[] byteArray,通常是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;
}
而且运行速度非常快!
【问题讨论】:
-
我认为这个问题更适合 codereview.stackexchange.com
-
@Fildor
BitConverter在这种情况下基本上是零使用;和 IMO 几乎任何其他;事实上,BitConverter上唯一真正有用的方法是.ToString(),作为在单元测试等中编写 hex 的一种懒惰方式,也许.IsLittleEndian可以查询 CPU 字节序跨度> -
@MarcGravell 不幸的是,我不得不同意。
标签: c# arrays performance bit