首页 > 解决方案 > 以正确的顺序复制位

问题描述

为了解析非托管数据的二进制流,我必须重新创建数据类型。数据被压缩,这意味着我读取了 2 个字节,它们实际上代表一个 6 位byte值和一个 10 位short值。

我需要做的就是将一个位序列从一个值复制到另一个值。我知道源值和目标值的起始位和长度。到目前为止,我已经提出了两种方法,它们都复制了正确的位,但不知何故以相反的顺序。

byte BitwiseCopy(short value, int sourceStartBit, int destStartBit, int bitCount)
{
    short result = 0;
    for (int i = 0; i < bitCount; i++)
        //result |= (byte) (value & (1 << sourceStartBit + i) | (result & (1 << (destStartBit + bitCount) - i)));
        result |= (short) (value & (1 << sourceStartBit + i));

    return (byte) (result >> ((destStartBit - bitCount) + sizeof(byte) * 8));
}

对于我的测试场景,我使用的是具有以下值的短路:

0000 0000 1101 0011
^15               ^0

我的目标是将这个短的第 4-7 位复制一个字节的第0-3位。

当我使用注释行(没有返回子句中的代码)方法或当前突出显示的方式时,我总是得到这个结果:

0000 1011
^7      ^0

所以我想要的,只是颠倒过来。我敢肯定它很小,但我在这里忽略了什么?我不明白为什么它会颠倒顺序。移位方法(直接按位复制并将其移动到正确的位置)不应该反转它,不是吗?

编辑:该方法总是有一个类型的输入short。我有 3 个参数:sourceStart是我从输入值开始复制的位(从低到高),destStart是我复制到目标的位(字节或短 - 我会为this)和bitCount是我想要复制的位数(从低位到高位)。

该方法必须以正确的顺序复制位。因此,例如CopyBitwise(input, 4, 0, 4)应该返回 (left: high, right: low order)0000 1011给定这个输入:

input [short]: ... 1011 0110
                   ^8th    ^0th

另一个:

input [short]: 1011 0110 0100 0111
               ^15th             ^0th
                    ^end ^start

CopyBitwise(input, 7, 3, 5)应该导致

0011 0000
^8th    ^0th
^end ^start

标签: c#bitwise-operatorsbit-shift

解决方案


你不需要一个循环!这应该可以解决问题:

byte BitwiseCopy(short value, int sourceStartBit, int destStartBit, int bitCount){
    byte result = (byte) ((value >> sourceStartBit) << destStartBit);
    result &= (byte) ~(0xff << bitCount); // mask for zeros at the left of result
    return result;
}

推荐阅读