改进位掩码和移位功能

时间:2011-08-18 13:33:30

标签: c# bitwise-operators masking

是否可以改进此功能以提高效率?:

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;
        }

我有一系列的uints。每个uint包含多个数据。为了获得信息,我传入比特数和这些比特的偏移量。使用该信息,我构建一个输出值。 偏移量通常在字节边界上,但我不能保证它会是。

我其实真的想看看我是否可以简化代码。我在代码中是不必要的冗长,还是可以做得更清洁?

更新功能:你们对此感觉如何?

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;
}

1 个答案:

答案 0 :(得分:0)

这需要测试(并假设bitsToGrab + bitsToMoveOver&lt; = 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;