从一个字节中抓取n位

时间:2013-03-06 18:57:53

标签: c++ c binary hex bits

我从一个字节中抓取n位有点麻烦。

我有一个无符号整数。假设我们的十六进制数是0x2A,十进制是42。在二进制文件中,它看起来像这样:0010 1010.我如何获取前10位是00101,接下来的3位是010,并将它们分成单独的整数?

如果有人能帮助我那会很棒!我知道如何从一个字节中提取,只需要做

int x = (number >> (8*n)) & 0xff // n being the # byte

我在另一篇关于堆栈溢出的文章中看到过,但我不确定如何从字节中获取单独的位。如果有人能帮助我,那就太好了!谢谢!

6 个答案:

答案 0 :(得分:18)

整数在机器内表示为一系列位;幸运的是,对于我们人类来说,编程语言提供了一种机制来向我们显示十进制(或十六进制)中的这些数字,但这并不会改变它们的内部表示。

您应该修改按位运算符&|^~以及移位运算符<<>>,这将有助于您了解如何解决此类问题。

整数的最后3位是:

x & 0x7

从最后8位开始的5位是:

x >> 3    // all but the last three bits
  &  0x1F // the last five bits.

答案 1 :(得分:13)

在C中“抓取”整数类型的部分如下:

  1. 您将所需的位移到最低位置。
  2. 您使用&来掩盖您想要的位 - 意味着“复制此位”,零意味着“忽略”
  3. 所以,在你的例子中。假设我们有一个数字int x = 42;

    前5位:

    (x >> 3) & ((1 << 5)-1);
    

    (x >> 3) & 31;
    

    要获取低三位:

    (x >> 0) & ((1 << 3)-1)
    

    或:

    x & 7;
    

答案 2 :(得分:8)

假设您希望从顶部开始hi位,从底部开始lo位。 (在你的例子中为5和3)

top = (n >> lo) & ((1 << hi) - 1)
bottom = n & ((1 << lo) - 1)

说明:

对于 top ,首先去掉低位(右移),然后使用“all one”掩码屏蔽剩余的(如果你有像0010000这样的二进制数字,减去一个结果0001111 - 与1相同数量的0 - 原始数字中的s。)

对于底部,它是相同的,只是不必关心初始转移。

top = (42 >> 3) & ((1 << 5) - 1) = 5 & (32 - 1) = 5 = 00101b
bottom = 42 & ((1 << 3) - 1) = 42 & (8 - 1) = 2 = 010b

答案 3 :(得分:5)

您可以使用位域。位域是特殊结构,您可以在其中指定位变量。

typedef struct {
  unsigned char a:5;
  unsigned char b:3;
} my_bit_t;

unsigned char c = 0x42;
my_bit_t * n = &c;
int first = n->a;
int sec = n->b;

位字段在http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000

中有更详细的描述

比特字段的魅力在于,您不必处理移位运算符等。符号非常简单。与操作位一样,存在可移植性问题。

答案 4 :(得分:1)

只需删除代码中的8 *。

int input = 42;
int high3 = input >> 5;
int low5 = input & (32 - 1); // 32 = 2^5
bool isBit3On = input & 4; // 4 = 2^(3-1)

答案 5 :(得分:1)

int x = (number >> 3) & 0x1f;

将给出一个整数,其中最后5位是number的8-4位,其他位是0。

同样,

int y = number & 0x7;

将给出一个整数,最后3位设置number的最后3位,其余为零。