从字节数组中提取位范围并创建一个新的整数

huangapple go评论57阅读模式
英文:

Extract bit range from byte array and create a new int

问题

需要从字节数组(小端)中提取位,然后组成一个新的整数。

假设我的字节数组如下:

[0b00011001, 0b11001001, 0b00101010, 0b11001110]

我需要提取位14到18(包括14和18)。

首先,我使用位掩码如下:

[0b00011001, 0b11000000, 0b00000010, 0b11001110],对第1个字节使用 & 0b11000000,对第2个字节使用 & 0b00000111

然后,移除第一个字节,并重置其他字节:

[0b11000000, 0b00000010, 0b00000000, 0b00000000]

如果我将这个字节数组转换为一个32位的无符号整数,结果是 704。这正确吗?

假设最高位(MSB)为7,最低位(LSB)为0,这是正确的吗?

英文:

I need to extract bits from a byte array (little endian), and then form a new int from it.

Say my byte array is this:

[0b00011001, 0b11001001, 0b00101010, 0b11001110]

And I need to extract bits 14 to 18 (inclusive).

First I bitmask like so:

[0b00011001, 0b11000000, 0b00000010, 0b11001110] using & 0b11000000 on [1] and & 0b00000111 on [2]

Then remove first byte, and reset other bytes:

[0b11000000, 0b00000010, 0b00000000, 0b00000000]

If I form an uint 32 out of this, it results in 704. Is this correct?

Is assuming MSB = 7 and LSB = 0 correct?

答案1

得分: -1

如评论中所提到的,使用union会更容易一些。

#include <stdio.h>
#include <stddef.h>

typedef union {
    uint32_t i;
    uint8_t c[4];
} u_t;

int main(void) {
    u_t u = {0};

    // 小端机器
    u.c[0] = 0x19; // 我相信这些是操作数据的十六进制等价物。
    u.c[1] = 0xC9;
    u.c[2] = 0x2A;
    u.c[3] = 0xCE;

    u.i &= 0x1F << (14-1); // 5位掩码,b14-b18

    printf("%08X\n", u.i);
    printf("%u\n", u.i);

    printf("%u\n", u.i >> 8); // 我(们)的错误

    printf("%u\n", u.i >> 14); // 可能是预期的结果

    return 0;
}
0002C000
180224
704
11

当然,这将更简单,只需一开始就将值右移,然后掩码获取最低的5位... C'est la guerre...

英文:

As mentioned in the comments, it would be much easier to work with a union.

#include &lt;stdio.h&gt;
#include &lt;stddef.h&gt;

typedef union {
	uint32_t i;
	uint8_t c[4];
} u_t;

int main( void ) {
	u_t u = { 0 };

	// Little Endian machine
	u.c[0] = 0x19; // I believe these are the hex equivalent of OP data.
	u.c[1] = 0xC9;
	u.c[2] = 0x2A;
	u.c[3] = 0xCE;

	u.i &amp;= 0x1F &lt;&lt; (14-1); // Mask for 5 bits, b14-b18

	printf( &quot;%08X\n&quot;, u.i );
	printf( &quot;%u\n&quot;, u.i );

	printf( &quot;%u\n&quot;, u.i &gt;&gt; 8 ); // my (our) mistake

	printf( &quot;%u\n&quot;, u.i &gt;&gt; 14 ); // Perhaps what was intended

	return 0;
}
0002C000
180224
704
11

Of course, this would be much simpler just shifting the value to the right to begin with, then mask for the 5 lowest bits... C'est la guerre...

huangapple
  • 本文由 发表于 2023年1月6日 14:51:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75027825.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定