C#语言:改变字节中的前四位

为了充分利用字节,我试图将两个唯一值存储到一个字节中:一个在前四位中,另一个在后四位中。 但是,我发现,虽然这种做法允许优化内存分配,但它使得更改存储在字节中的各个值变得困难。

在我的代码中,我想在一个字节中更改第一组四位,同时保持同一字节中后四位的值。 虽然按位运算允许我轻松检索和操作前四位值,但我发现很难将这个新值与一个字节中的第二组四位连接起来。 问题是,如何从一个字节中擦除前四位(或者更准确地说,将它们全部置零)并添加新的4位组以替换刚刚擦除的四位,从而保留最后4位改变前四个字节的位数?

这是一个例子:

// Changes the first four bits in a byte to the parameter value public void changeFirstFourBits(byte newFirstFour) { // If 'newFirstFour' is 0101 in binary, make 'value' 01011111 in binary, changing // the first four bits but leaving the second four alone. } private byte value = 255; // binary: 11111111 

使用按位AND( & )清除旧位,将新位移位到正确位置并按位OR( | )将它们组合在一起:

 value = (value & 0xF) | (newFirstFour << 4); 

这是发生的事情:

  value : abcdefgh newFirstFour : 0000xyzw 0xF : 00001111 value & 0xF : 0000efgh newFirstFour << 4 : xyzw0000 (value & 0xF) | (newFirstFour << 4) : xyzwefgh 

当我不得不这样做时,我会为我做一个只读结构。 当然,一个四位整数称为nybble:

 struct TwoNybbles { private readonly byte b; public byte High { get { return (byte)(b >> 4); } } public byte Low { get { return (byte)(b & 0x0F); } { public TwoNybbles(byte high, byte low) { this.b = (byte)((high << 4) | (low & 0x0F)); } 

然后在TwoNybbles和byte之间添加隐式转换。 现在,您可以将任何字节视为具有高字节和低字节,而不会在主线代码中放置所有那些丑陋的位。

首先使用value & 0xF屏蔽高四字节。 然后使用newFirstFour << 4将新位移到高四位,最后使用二进制或者将它们组合在一起。

 public void changeHighFourBits(byte newHighFour) { value=(byte)( (value & 0x0F) | (newFirstFour << 4)); } public void changeLowFourBits(byte newLowFour) { value=(byte)( (value & 0xF0) | newLowFour); } 

我不确定你的方法应该做什么,但这里有一些方法:

 void setHigh(ref byte b, byte val) { b = (b & 0xf) | (val << 4); } byte high(byte b) { return (b & 0xf0) >> 4; } void setLow(ref byte b, byte val) { b = (b & 0xf0) | val; } byte low(byte b) { return b & 0xf; } 

应该是不言自明的。

 public int SplatBit(int Reg, int Val, int ValLen, int Pos) { int mask = ((1 << ValLen) - 1) << Pos; int newv = Val << Pos; int res = (Reg & ~mask) | newv; return res; } 

例:

  • Reg = 135
  • Val = 9(ValLen = 4,因为9 = 1001)
  • Pos = 2

  • 135 = 10000111

  • 9 = 1001
  • 9 << Pos = 100100
  • 结果= 10100111

快速查看表示按位,可以使用&运算符实现。 因此,要删除前四个字节,您应该能够:

 byte value1=255; //11111111 byte value2=15; //00001111 return value1&value2; 

假设newVal包含您要在origVal中存储的值。 为4个最低有效位执行此操作:

 byte origVal = ???; byte newVal = ??? orig = (origVal & 0xF0) + newVal; 

这对于4个最重要的位:

 byte origVal = ???; byte newVal = ??? orig = (origVal & 0xF) + (newVal << 4); 

我知道你具体要求清除前四位,已经多次回答,但是我想指出,如果你有两个值<=十进制15,你可以简单地将它们组合成8位:

  public int setBits(int upperFour, int lowerFour) { return upperFour << 4 | lowerFour; } 

结果将是xxxxyyyy在哪里

 xxxx = upperFour yyyy = lowerFour 

这就是你似乎想要做的事情。

这里有一些代码,但我认为之前的答案会为你做。 这只是为了展示一些复制和过去的测试代码到一个简单的控制台项目中(WriteBits方法有帮助):

 static void Main(string[] args) { int b1 = 255; WriteBits(b1); int b2 = b1 >> 4; WriteBits(b2); int b3 = b1 & ~0xF ; WriteBits(b3); // Store 5 in first nibble int b4 = 5 << 4; WriteBits(b4); // Store 8 in second nibble int b5 = 8; WriteBits(b5); // Store 5 and 8 in first and second nibbles int b6 = 0; b6 |= (5 << 4) + 8; WriteBits(b6); // Store 2 and 4 int b7 = 0; b7 = StoreFirstNibble(2, b7); b7 = StoreSecondNibble(4, b7); WriteBits(b7); // Read First Nibble int first = ReadFirstNibble(b7); WriteBits(first); // Read Second Nibble int second = ReadSecondNibble(b7); WriteBits(second); } static int ReadFirstNibble(int storage) { return storage >> 4; } static int ReadSecondNibble(int storage) { return storage &= 0xF; } static int StoreFirstNibble(int val, int storage) { return storage |= (val << 4); } static int StoreSecondNibble(int val, int storage) { return storage |= val; } static void WriteBits(int b) { Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(b),0)); } }