C++ 从一个字节中抓取 n 位

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15255692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:12:48  来源:igfitidea点击:

Grabbing n bits from a byte

c++cbinaryhexbits

提问by user1871869

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. 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?

我有一个无符号整数。假设我们的十六进制数是 0x2A,十进制数是 42。在二进制中它看起来像这样:0010 1010。我如何获取前 5 位 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!

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

回答by rici

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.

回答by Mats Petersson

"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"
  1. 您将想要的位移到最低位置。
  2. &用来屏蔽你想要的位 - 一个表示“复制这个位”,零表示“忽略”

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;

回答by gaborsch

Say you want hibits from the top, and lobits from the bottom. (5 and 3 in your example)

假设您想要hi顶部的lo位,以及底部的位。(在您的示例中为 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 1s as you had 0-s in the original number).

对于顶部,首先去掉低位(右移),然后用“全为”掩码掩码剩余的位(如果您有一个二进制数,例如0010000,减去一个结果0001111- 与1您拥有的0s数量相同-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

回答by wirrbel

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.

位域的魅力在于,您不必处理移位运算符等。表示法非常简单。与操作位一样,存在可移植性问题。

回答by meyumer

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

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

will give you an integer where the last 5 bits are the 8-4 bits of numberand zeros in the other bits.

会给你一个整数,其中最后 5 位是 8-4 位,number其他位为零。

Similarly,

相似地,

int y = number & 0x7;

int y = number & 0x7;

will give you an integer with the last 3 bits set the last 3 bits of numberand the zeros in the rest.

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

回答by Dave

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)