英文:
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 << 4) | lo; // low 4 bits of 'first' OR'd with low 4 bits of 'second'
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 <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;
}
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 <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);
}
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论