改进了位掩码和移位功能

本文关键字:功能 掩码 | 更新日期: 2023-09-27 18:05:53

可以改进这个函数使其更有效吗?:

private unsafe uint GetValue(uint value, int bitsToGrab, int bitsToMoveOver)
        {
            byte[] bytes = BitConverter.GetBytes(value);
            uint myBitMask = 0x80;  //MSB of 8 bits (byte)
            int arrayIndex = 0;
            for (int i = 0; i < bitsToMoveOver; i++)
            {
                if (myBitMask == 0)
                {
                    arrayIndex++;
                    myBitMask = 0x80;
                }
                myBitMask >>= 1;
            }
            uint outputMask1 = (uint)(1 << (bitsToGrab - 1));
            uint returnVal = 0;
            for (int i = 0; i < bitsToGrab; i++)
            {
                if (myBitMask == 0)
                {
                    arrayIndex++;
                    myBitMask = 0x80;
                }
                if ((bytes[arrayIndex] & myBitMask) > 0)
                {
                    returnVal |= outputMask1;
                }
                outputMask1 >>= 1;
                myBitMask >>= 1;
            }
            return returnVal;
        }

我有一个单位数组。每个单元包含多个数据块。为了获得信息,我传入了比特数和这些比特的偏移量。使用这些信息,我构建一个输出值。偏移量通常在字节边界上,但我不能保证它一定在。

我真的很想看看我是否可以简化代码。我在代码中是否不必要地冗长,或者可以做得更简洁一点?

更新功能:你们觉得这个怎么样?

private unsafe uint GetValue(uint value, int bitsToGrab, int bitsToMoveOver)
        {
            if (bitsToGrab + bitsToMoveOver >= 32)
            {
                return 0;
            }
            byte[] bytes = BitConverter.GetBytes(value);
            Array.Reverse(bytes);
            uint newValue = BitConverter.ToUInt32(bytes, 0);
            uint grabMask = (0xFFFFFFFF << (32 - bitsToGrab));
            grabMask >>= bitsToMoveOver;
            uint returnVal = (newValue & grabMask) >> (32 - bitsToMoveOver - bitsToGrab);
            return returnVal;
}

改进了位掩码和移位功能

这需要测试(并假设bitsToGrab + bitstomover <= 32),但我认为你可以这样做:

uint grabMask = ~(0xFFFFFFFF << (bitsToGrab + bitsToMoveOver));
return (value & grabMask) >> bitsToMoveOver;

由于OP已经指示它应该从数字的内部二进制表示(包括端序编码)中采样位,并且在每个单词中进行字节顺序交换,因此您可以先像这样交换字节:

uint reorderedValue = ((value << 8) & 0xFF00FF00) | ((value >> 8) & 0x00FF00FF);
uint grabMask = ~(0xFFFFFFFF << (bitsToGrab + bitsToMoveOver));
return (reorderedValue & grabMask) >> bitsToMoveOver;