位编码。或将一个字节构造成几个与相应位相关的不同值。或按位编码或位操作

Coding in Bits. or Structuring a Byte into several different values with respect to corresponding bits. or Bitwise coding or Bit Manipulation

我想要单字节多功能

我想把一个Byte分成5份;即前半字节或前四位,具有 0-15 个不同的值。

然后字节的后半部分或最后4位必须分开,每个位(即第5、6、7或8th_bit)的值必须为0或1。

例如:如果我传递这样的值“0b 1111 1 1 1 1”。它应该配置为前 4 位 (0-15) 的值 15 中存在的功能,并且 5th_bit(0-1) 必须设置 (1) 或清除 (0) 才能执行某些功能和第 6 个、第 7 位和 8th_bit 也必须像第 5 位

一样做类似的事情

Maybe if you look into the image you might get what I am trying to say. Please click the link to see the image.我不确定标题,我认为标题符合我的问题。我想在 C++ 中实现这一点。如何做到这一点?这该怎么做?有例子吗?

你有几种方法:

  • 手动方式,手动执行 bitwise operations,例如:

    struct S
    {
    private:
        std::byte getPage() const { return (data & 0xF0) >> 4; }
        void setPage(std::byte value) { return data = (data & 0x0F) | ((value & 0x0F) << 4); }
    
        bool getCtrl1() const { return data & 0x08; } // 1 << 3
        bool getCtrl2() const { return data & 0x04; } // 1 << 2
        bool getCtrl3() const { return data & 0x02; } // 1 << 1
        bool getCtrl4() const { return data & 0x01; } // 1 << 0
    
        void setCtrl1(bool b) { data = (data & ~0x08) | (b ? 0x08 : 0x00); }
        void setCtrl2(bool b) { data = (data & ~0x04) | (b ? 0x04 : 0x00); }
        void setCtrl3(bool b) { data = (data & ~0x02) | (b ? 0x02 : 0x00); }
        void setCtrl4(bool b) { data = (data & ~0x01) | (b ? 0x01 : 0x00); }
    
    private:
        std::byte data;
    };
    
  • 使用bit field:

    struct S
    {
         std::byte pages : 4;
         std::byte ctrl1 : 1;
         std::byte ctrl2 : 1;
         std::byte ctrl3 : 1;
         std::byte ctrl3 : 1;
    };
    

    (但不保证订单)

您需要学习一点布尔代数知识。最重要的是 AND、OR 和 NOT 操作。您可以使用这 3 个操作构建任何东西。还有其他操作也可用于达到任何所需的结果,例如 NAND 和 NOR 等。但无论如何。

C++ 具有用于 AND & 或 OR | 或 NOT~ 的位运算符。请不要混淆布尔逻辑运算符 &&||! 适用于布尔表达式。

让我们看看位运算符的行为。在下面的例子中,我们总是在谈论一个 sinegle 位:

AND  Result      Or   Result     NOT  Result
a b    y         a b     y       a       y
---------        ----------      ---------- 
0 0    0         0 0     0       0       1 
0 1    0         0 1     1       1       0
1 0    0         1 0     1
1 1    1         1 1     1

不,我们需要了解,我们如何设置位和清除位。从上面table可以看出

  • Something AND 0 --> 始终为 0。因此,我们可以使用 AND 0
  • 清除位
  • Something OR 1 --> 总是 1。所以,我们可以用 OR 1
  • 设置一个位
  • Something AND 1 --> 总是“Something”。所以,与 1 的 AND 是一个中性运算
  • Something OR 0 --> 总是“Something”。所以,OR 与 0 是一个中性运算

好的。现在我们知道如何设置位或如何清除位。我们还可以进行多个位设置或位清除。所以,如果我们想设置一个字节的最高4位,我们可以这样写

byte = byte | 0b11110000. 

这将设置最高 4 位而不更改最低 4 位。

如果我们想delete/reset/set-to-0位号0和1,那么我们可以这样写:

byte = byte & 0b11111100. 

如果我们想知道几个位的值,我们可以“屏蔽”它们。我们可以创建一个二进制值,在我们想要读取的位置上设置位。例子。我们要读取最低的 3 位。

所以,

value = byte & 0b00000111. 

现在应该清楚了。 . . .

我们还有 2 个额外的重要操作,它们正在转移。由于位根据它们的位置具有不同的值,因此我们需要经常将它们移动到正确的位置。

在您的示例中,让我们将值 9 写入最高 4 位。我们需要做的是:

  1. 删除任何可能带有掩码的旧内容
  2. 创建值 9 并将其向右移动 4 个位置
  3. 删除移位值的低4位
  4. OR 超过目标值的结果
unsigned char value = 9;
value = value << 4;
value = value & 0b11110000;
Target = target | value;

当然,您可以在一条语句中完成所有这些操作。

读取最上面的 4 个值将是相反的方法。

value = target & 0b11110000;
value = value >> 4;
value = value & 0b00001111;

通过创建位模式(掩码),您可以影响所有需要的位