如何从两个4位(半字节)制作一个8位(字节)?

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

How to make an 8bit (byte) from two 4bits (nibbles)?

问题

假设我们有两个整数,5 和 C(十六进制表示为12),我们想要获得一个字符,该字符由第一个数字的4位和第二个数字的4位连接而成。在我的示例中,我需要获得一个具有以下位的字符:0101 1100。有人可以帮助我吗?谢谢!

这个问题源于以下情景:在我的程序中,我直接使用位来工作。为了处理位,我使用char数据类型。最初,我需要处理4位数字,但char的大小是8位。我有16个整数,它们是4位数字(0、1、...、15),我需要使用一个char来表示它们,为此我需要将两个整数放入一个char中。

英文:

Suppose we have 2 ints 5 and C(hexidecimal representation of 12) and we want to get a char, which is the concatenation of 4 bits of the first number and 4 bits of the second number. As a result in my example, i have to get a char with bits: 0101 1100. Can somebody help me? Thank you!

This issue arose from the following scenario: in my program I work directly with bits. To work with bits I use the char data type. Initially, I need to work with 4-bit numbers, but the char size is 8 bits. I have 16 int numbers, which are 4-bit numbers (0, 1, ..., 15), I need to write them using a char, and for this I need to put two ints in one char.

答案1

得分: 5

注意:OP说明'first'和'second'的值在0到15之间(包括0和15)。
unsigned char hi = 0x5, lo = 0xC, result;

result = (hi << 4) | lo; // 'first'的低4位与'second'的低4位进行按位或操作
应该可以了。
英文:

Caveat: OP states values of 'first' and 'second' are between 0 to 15 inclusive.

unsigned char hi = 0x5, lo = 0xC, result;

result = (hi &lt;&lt; 4) | lo; // low 4 bits of &#39;first&#39; OR&#39;d with low 4 bits of &#39;second&#39;

That should do it..

答案2

得分: 1

你可以为此目的定义一个宏:

#include <stdio.h>

#define CONCAT(x,y) (x) << 4 | (y)

int main(void)
{
    unsigned char val=0;
    val = CONCAT(5,0xc);
    printf("%x\n", val);

    return 0;
}

输出:

Success #stdin #stdout 0.01s 5460KB 
5c
英文:

You can define a Macro for this purpose:

#include &lt;stdio.h&gt;
 
#define CONCAT(x,y) (x) &lt;&lt; 4 | (y)
 
int main(void)
{
    unsigned char val=0;
    val = CONCAT(5,0xc);
    printf(&quot;%x\n&quot;, val);
 
    return 0;
}

Output:

Success #stdin #stdout 0.01s 5460KB 
5c

答案3

得分: 0

你可以使用位域union 来完成相同的操作。如果你在使用带有匿名 union 的 C11,那么可以更容易地实现如下:

#include <stdio.h>
#include <inttypes.h>

union two_nibbles {
    uint8_t byte;
    struct { uint8_t nibble2 : 4, nibble1 : 4; };
};

int main(void) {
    const union two_nibbles n = { .nibble1 = 0x05, .nibble2 = 0x0C };
    printf("byte 0x%" PRIX8 "\n", n.byte);
}

这很不错,但定义不够明确。标准只保证了int是一个位域。"实现可以分配足够大以容纳位域的任何可寻址存储单元。" (C99 §6.7.2.1) 我认为,这两个封装可能会以错误的顺序出现。另一方面,移位是明确定义的,但有时候会不方便和难以阅读。

英文:

You can use bit-fields and union to do the same thing. If you are using C11 with anonymous union, then one might do it more easily like,

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

union two_nibbles {
	uint8_t byte;
	struct { uint8_t nibble2 : 4, nibble1 : 4; };
};

int main(void) {
	const union two_nibbles n = { .nibble1 = 0x05, .nibble2 = 0x0C };
	printf(&quot;byte 0x%&quot; PRIX8 &quot;\n&quot;, n.byte);
}

This is very nice, but less well-defined. The only guaranteed bit-field mandated by the standard is int. "An implementation may allocate any addressable storage unit large enough to hold a bit-field." (C99 §6.7.2.1) The nibbles might conceivably might be in the wrong order, I think. On the other hand, shifting is well defined, but inconvenient and hard to read at times.

huangapple
  • 本文由 发表于 2023年2月24日 14:43:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75553332.html
匿名

发表评论

匿名网友

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

确定