简体   繁体   English

从一个字节中抓取n位

[英]Grabbing n bits from a byte

I'm having a little trouble grabbing n bits from a byte. 我从一个字节中抓取n位有点麻烦。

I have an unsigned integer. 我有一个无符号整数。 Let's say our number in hex is 0x2A, which is 42 in decimal. 假设我们的十六进制数是0x2A,十进制是42。 In binary it looks like this: 0010 1010. How would I grab the first 5 bits which are 00101 and the next 3 bits which are 010, and place them into separate integers? 在二进制文件中,它看起来像这样:0010 1010.我如何获取前10位是00101,接下来的3位是010,并将它们分成单独的整数?

If anyone could help me that would be great! 如果有人能帮助我那将是伟大的! I know how to extract from one byte which is to simply do 我知道如何从一个字节中提取即可

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

which I saw on another post on stack overflow, but I wasn't sure on how to get separate bits out of the byte. 我在另一篇关于堆栈溢出的文章中看到过,但我不确定如何从字节中获取单独的位。 If anyone could help me out, that'd be great! 如果有人能帮助我,那就太好了! Thanks! 谢谢!

Integers are represented inside a machine as a sequence of bits; 整数在机器内表示为一系列位; fortunately for us humans, programming languages provide a mechanism to show us these numbers in decimal (or hexadecimal), but that does not alter their internal representation. 幸运的是,对于我们人类来说,编程语言提供了一种机制来向我们显示十进制(或十六进制)中的这些数字,但这并不会改变它们的内部表示。

You should revise the bitwise operators & , | 你应该修改按位运算符&| , ^ and ~ as well as the shift operators << and >> , which will help you understand how to solve problems like this. ^~以及移位运算符<<>> ,这将帮助您了解如何解决这样的问题。

The last 3 bits of the integer are: 整数的最后3位是:

x & 0x7

The five bits starting from the eight-last bit are: 从最后八位开始的五位是:

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

"grabbing" parts of an integer type in C works like this: 在C中“抓取”整数类型的部分是这样的:

  1. You shift the bits you want to the lowest position. 您将所需的位移到最低位置。
  2. You use & to mask the bits you want - ones means "copy this bit", zeros mean "ignore" 你使用&来掩盖你想要的位 - 意思是“复制这个位”,零意味着“忽略”

So, in you example. 所以,在你的例子中。 Let's say we have a number int x = 42; 假设我们有一个数字int x = 42;

first 5 bits: 前5位:

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

or 要么

(x >> 3) & 31;

To fetch the lower three bits: 要获取低三位:

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

or: 要么:

x & 7;

Say you want hi bits from the top, and lo bits from the bottom. 假设你想hi从顶部位, lo从下位。 (5 and 3 in your example) (在你的例子中为5和3)

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

Explanation: 说明:

For the top , first get rid of the lower bits (shift right), then mask the remaining with an "all ones" mask (if you have a binary number like 0010000 , subtracting one results 0001111 - the same number of 1 s as you had 0 -s in the original number). 对于顶部 ,先干掉的下位(右移),然后屏蔽与“所有的人”面具剩余的(如果你有一个二进制数字,如0010000 ,减去一个结果0001111 -相同数量的1 S作为你在原始数字中有0 -s)。

For the bottom it's the same, just don't have to care with the initial shifting. 对于底部它是相同的,只是不必关心初始转移。

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

You could use bitfields for this. 您可以使用位域。 Bitfields are special structs where you can specify variables in bits. 位域是特殊结构,您可以在其中指定位变量。

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;

Bit fields are described in more detail at http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000 比特字段在http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000中有更详细的描述

The charm of bit fields is, that you do not have to deal with shift operators etc. The notation is quite easy. 位域的魅力在于,您不必处理移位运算符等。符号非常简单。 As always with manipulating bits there is a portability issue. 与操作位一样,存在可移植性问题。

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

will give you an integer where the last 5 bits are the 8-4 bits of number and zeros in the other bits. 将给出一个整数,其中最后5位是8-4位的number和其他位中的零。

Similarly, 同样的,

int y = number & 0x7;

will give you an integer with the last 3 bits set the last 3 bits of number and the zeros in the rest. 会给你一个整数设定的最后3位的后3位number ,并在其余的零。

just get rid of the 8* in your code. 只需删除代码中的8 *。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM