【问题标题】:C++: Bitwise ANDC++:按位与
【发布时间】:2012-04-29 15:11:16
【问题描述】:

我试图了解如何使用按位与来提取单个字节的值。

我拥有的是一个 4 字节数组,并将最后 2 个字节转换为一个 2 字节值。然后我试图从那个 2 字节值中提取原始的单字节值。有关我的代码和值的屏幕截图,请参见附件。

我遇到的问题是我无法获取 2 字节值中最后一个字节的值。

我将如何使用按位与来执行此操作?

【问题讨论】:

  • 实际上使用您发布的代码,调试器中显示的x & 0x00FF 确实产生了正确的结果,所以我不确定您认为预期的结果应该是什么?
  • 说实话,我期待的结果是 4,因为 ((char*)&x)[1] 是 4
  • 见大卫罗德里格斯的回答。
  • signed short to byte in c++ 的可能重复项

标签: c++ byte bit-manipulation bit


【解决方案1】:

我遇到的问题是我无法获取 2 字节值中最后一个字节的值。

您的 2 字节整数由值 3 和 4 组成(因为您的指针指向 a[1])。正如您在测试中已经看到的,您可以通过应用掩码0xFF 来获得3。现在,要获得4,您需要删除低位移动该值。在您的示例中,通过使用掩码 0xFF00,您可以有效地从 16 位数字中删除 3,但是您将 4 留在 2 字节数字的高字节中,即值 1024 == 2^10 - 第 11 位set,也就是第二个字节中的第三位(从最小代表开始算)

您可以将该结果向右移动 8 位以获得您的 4,否则您可以完全忽略掩码,因为只需向右移动最低位就会消失

4 == ( x>>8 )

按位测试更有趣的结果,可以通过使用单个数字来获得:

int x = 7;              // or char, for what matters:
(x & 0x1) == 1;
(x & (0x1<<1) ) == 2;   // (x & 0x2)
(x & ~(0x2)) == 5;

【讨论】:

  • 16 位变量中的值应该是 3 和 4,因为在访问索引之前数组被强制转换为 uint16_t
  • 有趣。因此,如果我想要 2 字节值中的第二个半字节,我会执行以下操作: (x >> 4) & 0xF00
  • "你把 4 留在你的 2byte 数字的高字节,这是值 1024 == 2^10 -- 第 11 位设置,这是第二个字节中的第二位" 实际上是第三位;)
  • @rhughes:是的,我错过了演员是在间接之前。我做的数学是错误的,试图将结果与我的预期结果相匹配。我已经更正了答案(只是替换数字)——这解释了字节序的奇怪行为
  • @rhughes:我认为这是不对的 (x>>4) & 0xF00。请注意,该表达式在高字节中设置了四个位。如果你想要最高半字节,你会做(x &gt;&gt; 12) &amp; 0xF,对于最高字节中的最低半字节(x &gt;&gt; 8) &amp; 0xF等等。在原始表达式中,您会得到正确的 4 位,但位置错误。
【解决方案2】:

您需要添加一些位移来将掩码值从高字节转换为低字节。

【讨论】:

  • 你有例子吗?我假设(错误地我现在知道)x & 0x00FF 将是较低的字节,因为它有 2 个 0。每个数字不代表半字节吗?
  • @rhughes:问题出在0xFF00 掩码上,而不是0x00FFx &amp; 0xFF00 产生 0x0400,而不是 0x0004
【解决方案3】:

我遇到的问题是我无法获得最后一个的值 字节中的 2 字节值。

不确定该“监视”表来自何处或是否涉及更多代码,但在我看来结果是正确的。请记住,其中一个是高字节,因此值移动

【讨论】:

  • 我想我现在明白了。 x & 0x00FF 不会删除第一个字节,它只是将其设置为 0。因此结果值为 0000 0000
  • 是的,这就是 AND 的工作原理。如果两个值都没有设置一个位,则结果为零。因此 0x00FF “屏蔽”了高字节,因为如果这些位不在掩码中,则无法在两个值中设置它们。剩下的只是在另一个值的低字节中设置的位。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-28
  • 2022-10-13
  • 1970-01-01
  • 1970-01-01
  • 2013-09-10
  • 2016-06-24
  • 1970-01-01
相关资源
最近更新 更多