C在一个字节中存储2个数字

时间:2011-10-27 09:03:13

标签: c binary bit-shift

u_char  ip_vhl;     /* version << 4 | header length >> 2 */

我做不到,这是怎么做到的? 你能举例说明如何使用这个字节存储这两个数字 知道每一个都是4位

5 个答案:

答案 0 :(得分:5)

如果每个数字是4位,则您将使用该字符的最低8位。在许多情况下,这将是所有的位。

这样做:

ip_vhl = ((version & 15) << 4) | (length & 15);

假设version是您想要的高位,length是您想要的最低位。 & 15确保每个值仅为4位。这主要是length值所需要的,以避免在长度大于15时覆盖专用于version的位。十进制常量15将以十六进制写入({{1许多人认为风格和品味都很清晰。

另一种编写“n个最右边的位设置为1,其他所有设置为0的整数”的方法是0xf,因为0x0f,我们可以使用((1 << n) - 1) },当然评估为n = 4

您的代码似乎首先将((1 << 4) - 1)分开并保存,如果这是您想要做的,您应该在将其打包到单个15之前执行此操作,为清楚起见:

length

答案 1 :(得分:2)

版本(a)使用位字段

struct entry {
  unsigned char version : 4;
  unsigned char length  : 4;
} ip_vhl;

ip_vhl.version = version;
ip_vhl.length = length;

版本(b)算术

ip_vhl = (version << 4) | (length & 0xF)
version = ip_vhl >> 4;
length  = ip_vhl & 0xf;

答案 2 :(得分:1)

// Here we are trusting that version and length are both < 0xF
unsigned char ip_vhl = (unsigned char)version << 4 | (unsigned char)length;

unsigned char version = ip_vhl >> 4;
unsigned char length = ip_vhl & 0xF;

答案 3 :(得分:1)

ip_vhl = (version << 4) | (headerlen & 0xf);

然后字节将如下所示:

VVVVHHHH

要取回原始值:

version = ip_vhl >> 4;
headerlen = ip_vhl & 0xf;

答案 4 :(得分:1)

此外,您可以求助于具有位字段的结构:

typedef struct s_ip_vhl 
{
    int version : 4;
    int header_length : 4;
} ip_vhl_type;

ip_vhl_type my_ip_vhl;
my_ip_vhl.version = 4;
my_ip_vhl.header_length = 5;
unsigned char byte = *((byte*)(&my_ip_vhl));

或者您可以使用带有unsigned char的联合打包结构,以便一次性获取整个字节:

typedef union u_ip_vhl
{
    typedef struct s_ip_vhl 
    {
        int version : 4;
        int header_length : 4;
    } ip_vhl_type;
    unsigned char byte;
} ip_vhl_union;