在C中提取位

时间:2017-01-25 14:41:27

标签: c extract

我对C编程有点新意,我对这个问题感到有些困惑:

假设您有一个带有符号整数(int)变量x,y和z的C程序。所有 变量包含一些任意值。编写一个C语句,用于提取位 从x索引17到13并将它们作为z中的最低有效位,并提取 y的至少3个有效位,并将它们放在z中索引为7到5的位中。没有其他 除了从x和y提取的8位之外,还应该改变z的位。注意 位索引0是最低有效位。你的答案应该包含一个C 声明以及声明不同部分的简短说明。

据我所知,如果我没有错,那么提取就像转移一样。

但有人可以给我一些关于如何解决这个问题的提示吗?

谢谢,所有的帮助都会得到满足!

1 个答案:

答案 0 :(得分:3)

从x:

中提取位
int b = x & 0x3E000;  /* x AND (...) 0011 1110 0000 0000 0000*/

移位提取的位:

b = b >> 13; /* 13 bits to the right, so that they land up starting on the first position */

清除z:

中的位
z &= 0xFFFFFFE0; /* z AND 1111 1111 1111 1111 1111 1111 1110 0000 */

将位应用于z:

z |= b;

从y:

中提取位
b = y & 0x3; /* y AND (...) 0000 0111 */ 

移位提取的位:

b = b << 5; /* move them 5 bits to the left so that they end up starting on position 5 */

清除z:

中的位
z &= 0xFFFFFF1F; /* z AND 1111 1111 1111 1111 1111 1111 0001 1111 */

将位应用于z:

z |= b;

现在,您可以将“清除”组合到一个操作中:

z &= 0xFFFFFF00; /* z AND 1111 1111 1111 1111 1111 1111 0000 0000 */

所有这一切都在一个声明中:

z = (z & 0xFFFFFF00) | ((y & 0x3) << 5) | ((x & 0x3E000) >> 13);

这适用于32位整数,或int32_t(C99及更高版本)。 使用64位整数(int64_t),您只需使用0xFFFFFFFFFFFFFF00作为“清除掩码”。

如果您使用的是vanilla int变量,请使用以下内容获取位数:

printf("int has %ud bits\n", sizeof(int) * 8);

sizeof()返回一个整数的字节大小,然后将该结果乘以8(99.999%的情况下每字节位数)以获得整数的位大小,从而得到大小你必须申请的面具。

一般来说:

  • 通过应用AND掩码提取位,每个位设置为0,除了要提取的那些,您将设置为1.原因是0 AND X = 0,但是1 AND X = X. / LI>
  • 将位移到您需要的位置。

  • 通过应用AND掩码清除位,每个位设置为1,除了要清除的位,您将设置为0.原因与上面相同。

  • 使用OR运算应用位。您必须确保要在目标上修改的位设置为0,并且您不想在原点上修改的位设置为0.原因是1 OR X = 1,但是0或X = X。