合并位移

时间:2011-02-14 13:42:45

标签: c++

我试图从一个字节中确定一个3位值,例如:

unsigned char r = ((253 << 5) >> 5);

结果值应为5,但为什么返回253?

3 个答案:

答案 0 :(得分:8)

两种可能性:

  • 您的表达式将被计算为整数,并最终转换为单词字节值。
  • 您的编译器会优化转换操作。

请注意,您的结果应该是5,而不是3.您想要的是:

const unsigned char c = 253 & 0x07 ; // (00000111)

你的位掩码是:

253 | 1 1 1 1 1 1 0 1 | F D
  7 | 0 0 0 0 0 1 1 1 | 0 7
+++++++++++++++++++++++++++
  5 | 0 0 0 0 0 1 0 1 | 0 5

答案 1 :(得分:3)

使用整数评估您的表达式。将其更改为:

unsigned char r = ((unsigned char)(253 << 5) >> 5);

你应该得到理想的结果。

答案 2 :(得分:1)

由于整数提升。表达式253 << 5中没有任何内容限制它仅在一个字节中工作;文字253的类型是int

您需要使用蒙版添加演员表,或者(更好的是,在我看来)提取物。要从整数中获取最低三位,只需使用:

const unsigned char r = 253 & ~((1 << 3) - 1);

这是因为1&lt;&lt; 3是8 10 ,其二进制是00001000 2 。我们减1,得到7 10 或00000111 2 。我们将其反转,得到一个掩码,其中包括除最右边的三个位之外的所有内容,即11111000 2 。然后按位进行逐位处理以进行提取。

上图中,我仅使用8位显示二进制值,在左侧扩展为零,直到平台的int大小,因为上述操作使用int精度完成。