C# 在一个字节中设置一些连续的位

C# 在一个字节中设置一些连续的位,c#,byte,bit-manipulation,bit,C#,Byte,Bit Manipulation,Bit,我需要一个具有以下签名的有效方法: public byte SetBits(byte oldValue, byte newValue, int startBit, int bitCount) 它返回oldValue,仅从它的startbit位开始直到它的startbit+bitcount位以零为基础,它被替换为newValue的第一个bitcount位 例如,如果: oldValue=11101101 新值=1000011 startBit=1 比特数=2 结果将是:11101111旧值中的段

我需要一个具有以下签名的有效方法:

public byte SetBits(byte oldValue, byte newValue, int startBit, int bitCount)
它返回oldValue,仅从它的startbit位开始直到它的startbit+bitcount位以零为基础,它被替换为newValue的第一个bitcount位

例如,如果:

oldValue=11101101 新值=1000011 startBit=1 比特数=2 结果将是:11101111旧值中的段10替换为新值中相应的段11


这里有一些大脑编译的代码,但如果我正确地阅读了问题,它应该符合您的要求。

给您。。。位双向移动以获取掩码。。。然后使用它生成新字节

public static byte SetBits(byte oldValue, byte newValue, int startBit, int bitCount)
{
    if (startBit < 0 || startBit > 7 || bitCount < 0 || bitCount > 7 
                     || startBit + bitCount > 8)
        throw new OverflowException();

    int mask = (255 >> 8 - bitCount) << startBit;
    return Convert.ToByte((oldValue & (~mask)) | ((newValue << startBit) & mask));
}

如果我理解你的问题,我想这就是你想要的:

byte mask = 0xFF;
for (int i = startPos-1; i < numBits; i++)
{
     if ((newValue & (1 << i)) == 1)
     {
          mask = (byte)(mask | (1 << i));
     }
     else
     {
          mask = (byte)(mask &~(1<<i));
     }
 }
 return (byte)(oldValue & mask);
这段代码基于


我知道在初始化为0xFF的字节中设置一个位实际上是不可行的,但我觉得应该保留代码,因为它可以帮助显示真正发生了什么。我鼓励代码用户根据需要对其进行优化。

顺便说一句,返回字节的void方法非常酷;[无意冒犯:]我刚刚完成了一个12小时的内核调试会话,所以我希望我的代码可以帮助您:通过调试,我的意思是每当内核挂起时,都会对监视器大喊大叫。|=不会在oldValues中为零感谢捕捉到这一点,将修复:标志在每次调用期间不会更改。你必须让flag成为一个代表,然后发出1声呜呜声我明白你的意思了,我不小心把startBit@Jesus:我仍然认为你最终几乎总是会得到0作为oldValue。例如,首先针对0001000进行遮罩,然后针对0010000进行遮罩。我认为你需要在循环中构建你的面具,然后应用面具。而且,如果你想替换那些比特,我认为三重-&也行不通。你可能想同时屏蔽oldValue、反向屏蔽newValue和|结果。GJ谢谢,这看起来和我最后做的很相似,只是比我预测的更有效-一旦我测试了你的解决方案就会接受OK,我需要做一些小的修改我已经相应地编辑了你的答案,现在它工作了well@ohadsc啊。。。从右侧索引的0。。。我的实现是从左侧开始的。很高兴您根据自己的需要对其进行了调整。@deepee1,等等,您真的从最左边的有效边索引了位号吗??
byte mask = 0xFF;
for (int i = startPos-1; i < numBits; i++)
{
     if ((newValue & (1 << i)) == 1)
     {
          mask = (byte)(mask | (1 << i));
     }
     else
     {
          mask = (byte)(mask &~(1<<i));
     }
 }
 return (byte)(oldValue & mask);