установить несколько последовательных битов в байте - PullRequest
1 голос
/ 20 июля 2011

Мне нужен эффективный метод со следующей подписью:

public byte SetBits(byte oldValue, byte newValue, int startBit, int bitCount)

Возвращает oldValue, но только начиная с его startbit бита до startbit + bitcount бита (с нуля) он заменяется первыми bitcount битами newValue

Например, если:

  • oldValue = 11101101
  • newValue = 10000011
  • startBit = 1
  • bitCount = 2

Тогда результат будет: 11101111 (сегмент 10 в oldValue заменяется соответствующим сегментом 11 в newValue)

Ответы [ 3 ]

4 голосов
/ 20 июля 2011

Вот, пожалуйста ... Сдвиньте в обоих направлениях, чтобы получить маску ... затем используйте ее для генерации нового байта

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));
}
0 голосов
/ 20 июля 2011

Если я понял ваш вопрос, я думаю, что это то, что вам нужно:

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, на самом деле запрещена, но я чувствовал, что код следует оставить, поскольку он может помочь показать, что на самом деле происходит.Я призываю пользователей кода оптимизировать его по мере необходимости.

0 голосов
/ 20 июля 2011
startBit--; //account for 0 indexing
byte flag = 1 << startBit;
for (int i = startBit; i < bitCount; i++, flag <<= 1)
{
    byte mask = newValue & flag;
    if (mask != 0)
        oldValue |= mask;
    else
        oldValue &= ~(flag);
}
return oldValue;

Здесь скомпилирован мозговой код, но он должен быть таким, каким вы хотите, если я правильно прочитал вопрос.

...