将位转换为整数 [英] converting bits in to integer

查看:101
本文介绍了将位转换为整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到一个包含字节数组的数据包,我必须从中获取一些整数值. 这是文档的一部分.有人可以帮我吗?

I receive a datapacket containing a byte array and I have to get some integer values from it. Here is a part of the documentation. Can someone help me please?

这是一个4字节数组.

从1990年到2052年的年份(6位),从1年到12月的月份(4位),从1天开始的一天 到31(5位),小时从0到23(5位),分钟从0到59(6位), 从0到59(6位)的秒数,默认值:2000年1月1日,12:00:00

Year from 1990 to 2052 (6 bit), Month from 1 to 12 (4 bit), Day from 1 to 31 (5 bit), Hour from 0 to 23 (5 bit), Minute from 0 to 59 (6 bit), Second from 0 to 59 (6 bit) Default value: 1 January 2000, 12:00:00

邮件的格式为小端.

推荐答案

您需要的是一些按位操作.首先,从字节中构造一个整数:

What you need is some bitwise operations. First, construct an int out of the bytes:

int n = b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);

然后,将int切成组件.现在,您的问题没有指定字段从右到左或从左到右的方向.这个问题与字节序有关,但不完全相同.因此,我们假设字段从左到右.

Then, chop up the int into components. Now, your question does not specify which way do the fields go, right-to-left or left-to-right. That question is related to endianness, but not identical. So let's assume that the fields go from left to right.

良好的意识表明从左到右.这样,可以比较时间值的整数表示形式-年位的重要性大于月位等,因此,当您比较对应于两个时间点的整数时,您将获得按时间顺序正确的结果.

Good sense suggests left-to-right. This way the integer representations of time values can be compared - the significance of year bits is more than month bits etc, so when you compare integers that correspond to two moments in time, you get a chronologically correct result.

这是给您的心理印象.这是一个整数变量,由位组成:

Here's a mental image for you. This is an integer variable, composed of bits:

f e d c b a 9 8 7 6 5 4 3 2 1 0
            -----
              offset is 6, length is 3

让我们定义一个函数,该函数以给定的偏移量(以位为单位)以给定的长度(以位为单位)从int中获取任意块.

Let's define a function that takes a arbitrary chunk from an int at a given offset (in bits), with a given length (in bits).

int bits(int n, int offset, int length)
{
    //shift the bits rightward, so that the desired chunk is at the right end
    n = n >> (31 - offset - length); 

    //prepare a mask where only the rightmost `length`  bits are 1's
    int mask = ~(-1 << length);

    //zero out all bits but the right chunk
    return n & mask;
}

本来可以是单线的,但我想使它具有启发性.下面的答案中的人通过为每个块手动指定移位因子和掩码来有效地内联此功能.

Could've been a one-liner, but I wanted to make it somewhat instructive. Folks in the answers below effectively inline this function, by specifying the shift factor and the mask by hand for each chunk.

现在让我们分解.假设n来自最上面的代码段:

Now let's decompose. Assuming n comes from the topmost snippet:

int year  = bits(n, 0,  6),
    month = bits(n, 6,  4),
    day   = bits(n, 10, 5),
    hour  = bits(n, 15, 5),
    min   = bits(n, 20, 6),
    sec   = bits(n, 26, 6);

我们通过将先前字段的总长度组合在一起来获得偏移量的值.这是基于以下假设:字段从左到右;如果它们相反,则偏移值将不同.

We get the values of the offset by combining the total lengths of the previous fields together. This is under the assumption that the fields go left to right; if they go the other way around, the offset values would be different.

这有意义吗?

如果位块从右移到左,那么这将是这样:

if the bit chunks go right to leftt, then here's how it'd go:

int sec   = bits(n, 0,  6),
    min   = bits(n, 6,  6),
    hour  = bits(n, 12, 5),
    day   = bits(n, 17, 5),
    month = bits(n, 22, 4),
    year  = bits(n, 26, 6);

这篇关于将位转换为整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆