Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用位运算符将多个值打包到一个int中_Java_Bitwise Operators_Packing_Bit Packing - Fatal编程技术网

Java 使用位运算符将多个值打包到一个int中

Java 使用位运算符将多个值打包到一个int中,java,bitwise-operators,packing,bit-packing,Java,Bitwise Operators,Packing,Bit Packing,低级位操作从来不是我的强项。我将理解一些帮助理解比特操作的下列用例。考虑……/P> int age, gender, height, packed_info; . . . // Assign values // Pack as AAAAAAA G HHHHHHH using shifts and "or" packed_info = (age << 8) | (gender << 7) | height; // Unpack with shifts and m

低级位操作从来不是我的强项。我将理解一些帮助理解比特操作的下列用例。考虑……/P>
int age, gender, height, packed_info;

. . .   // Assign values 

// Pack as AAAAAAA G HHHHHHH using shifts and "or"
packed_info = (age << 8) | (gender << 7) | height;

// Unpack with shifts and masking using "and"
height = packed_info & 0x7F;   // This constant is binary ...01111111
gender = (packed_info >> 7) & 1;
age    = (packed_info >> 8);
int年龄、性别、身高、包装信息;
. . .   // 赋值
//使用班次和“或”将包装为AAAAA G HHHHHHHHHH
打包信息=(7岁)和1岁;
年龄=(打包信息>>8);
我不确定这段代码实现了什么以及如何实现?为什么要使用神奇的数字0x7F?包装和拆包是如何完成的


这可能是位操作的一个相当长的课程,但首先让我也向您指出

解包的操作与此相反,但使用0x7F(即0b 01111111)之类的掩码来修剪字段中的其他值

gender = (packed_info >> 7) & 1;
工作起来就像

gender = 0b1011 /* shifted 7 here but still has age on the other side */
       & 0b0001
/* which is */
gender = 0b1

请注意,将任何内容与1进行and运算与“保留”该位相同,与0进行and运算与“忽略”该位相同。

您可以将表达式
x&mask
视为一种操作,该操作从
x
中删除
mask
中不存在的位(即值为0)。这意味着,
packed_info&0x7F
packed_info
中删除第七位以上的所有位

示例:如果
packed_info
是二进制的
1110010101010
,则
packed_info&0x7f
将被删除

1110010100101010
0000000001111111
----------------
0000000000101010
因此,在
height
中,我们得到
packed_info
的较低7位

接下来,我们将整个
packed_info
移位7,这样我们就删除了已经读出的信息。因此,我们得到(对于上一个示例中的值)
111001010
性别存储在下一位,因此使用相同的技巧:
&1
我们仅从信息中提取该位。其余信息包含在偏移量8处

打包也不复杂:你将
年龄
,将其移位8位(因此你从
11100101
得到
1110010100000000
),将
性别
移位7位(因此你得到
00000000
),然后取高度(假设它适合较低的7位)。然后,您要将它们组合在一起:

1110010100000000
0000000000000000
0000000000101010
----------------
1110010100101010

正如评论所说,我们将把年龄、性别和身高分成15位,格式如下:

AAAAAAAGHHHHHHH
让我们从这一部分开始:

(age << 8)
其中每个A可以是0或1


左移位运算符的意思是“乘以2,多次”。在二进制中,将一个数字乘以二等于在右边加一个零

右换档操纵器与左换档操纵器相反

管道操作符是“或”,意思是将两个二进制数叠加在一起,如果其中任何一个数中都有1,则该列中的结果为1

那么,让我们提取打包信息的操作:

// Create age, shifted left 8 times:
//     AAAAAAA00000000
age_shifted = age << 8;

// Create gender, shifted left 7 times:
//     0000000G0000000
gender_shifted = gender << 7;

// "Or" them all together:
//     AAAAAAA00000000
//     0000000G0000000
//     00000000HHHHHHH
//     ---------------
//     AAAAAAAGHHHHHHH
packed_info = age_shifted | gender_shifted | height;

如果你想把一个日期存储为一个数字,也许你可以通过将年份乘以10000,将月份乘以100,再加上日期来完成。2011年7月2日等日期将编码为数字20110702:

    year * 10000 + month * 100 + day -> yyyymmdd
    2011 * 10000 + 7 * 100 + 2 -> 20110702
我们可以说,我们将日期编码为yyyymmdd掩码。我们可以把这次行动描述为

  • 将第4年的位置向左移动
  • 将第2个月的位置向左和向右移动
  • 让这一天保持原样
  • 然后将这三个值组合在一起
这与年龄、性别和身高编码发生的事情是一样的,只是作者的思维是二进制的

请参见这些值可能具有的范围:

    age: 0 to 127 years
    gender: M or F
    height: 0 to 127 inches
如果我们将这些值转换为二进制,我们将得到:

    age: 0 to 1111111b (7 binary digits, or bits)
    gender: 0 or 1 (1 bit)
    height: 0 to 1111111b (7 bits also)
考虑到这一点,我们可以使用掩码对年龄-性别-身高数据进行编码aaaaaaaaa ghhhhh,只是这里我们讨论的是二进制数字,而不是十进制数字

所以

  • 将年龄8向左移动
  • 将性别7位左右移动
  • 保持高度不变
  • 然后将这三个值组合在一起

在二进制中,左移位运算符(是一个更简洁的答案:

aaaaaag hhhhh

包装:


Where
(1 3*@offset)和((1我曾多次遇到过相同的要求。借助于按位AND运算符,这是非常容易的。只需使用两(2)的递增幂来限定您的值。要存储多个值,请将它们的相对数(2的幂)相加并得到总和。此总和将合并您选择的值。如何

只需对每个值按位执行AND,它将为未选择的值提供零(0),为已选择的值提供非零

解释如下:

1) 价值观(是、否、可能)

2) 两(2)人的权力分配

3) 我选择是,可能因此得出结论:

SUM    =    1    +    4    =    5

SUM    =    00000001    +    00000100    =    00000101 
该值将同时存储YES和MAYBE。怎么做

1    &    5    =    1    ( non zero )

2    &    5    =    0    ( zero )

4    &    5    =    4    ( non zero )
因此,总和包括

1    =    2^0    =    YES
4    =    2^2    =    MAYBE.

要获得更详细的解释和实现,请访问我的

,我认为在问这个问题之前,有必要阅读有关二进制数表示和位运算符的内容。评论中的图片几乎说明了一切:aaaaaaaag hhhhh感谢您提供的详细信息。它非常有用。这是一篇非常好的文章。在我读到的所有东西中,这是第一件清楚地说明发生了什么的事情。
0011 & 0101 = 0001
packed_info          = AAAAAAAGHHHHHHH
0x7F                 = 000000001111111
(packed_info & 0x7F) = 00000000HHHHHHH = height
packed_info            = AAAAAAAGHHHHHHH
(packed_info >> 7)     = 0000000AAAAAAAG
1                      = 000000000000001
(packed_info >> 7) & 1 = 00000000000000G
// Create age, shifted left 8 times:
//     AAAAAAA00000000
age_shifted = age << 8;

// Create gender, shifted left 7 times:
//     0000000G0000000
gender_shifted = gender << 7;

// "Or" them all together:
//     AAAAAAA00000000
//     0000000G0000000
//     00000000HHHHHHH
//     ---------------
//     AAAAAAAGHHHHHHH
packed_info = age_shifted | gender_shifted | height;
// Grab the lowest 7 bits:
//     AAAAAAAGHHHHHHH &
//     000000001111111 =
//     00000000HHHHHHH
height = packed_info & 0x7F;

// right shift the 'height' bits into the bit bucket, and grab the lowest 1 bit:
//     AAAAAAAGHHHHHHH 
//   >> 7 
//     0000000AAAAAAAG &
//     000000000000001 =
//     00000000000000G
gender = (packed_info >> 7) & 1;

// right shift the 'height' and 'gender' bits into the bit bucket, and grab the result:
//     AAAAAAAGHHHHHHH 
//   >> 8
//     00000000AAAAAAA
age    = (packed_info >> 8);
    year * 10000 + month * 100 + day -> yyyymmdd
    2011 * 10000 + 7 * 100 + 2 -> 20110702
    age: 0 to 127 years
    gender: M or F
    height: 0 to 127 inches
    age: 0 to 1111111b (7 binary digits, or bits)
    gender: 0 or 1 (1 bit)
    height: 0 to 1111111b (7 bits also)
    (age << 8) | (gender << 7) | height
    height = value & 1111111b (preserve the 7 rightmost bits)
    gender = (value >> 1) & 1 (preserve just one bit)
    age = (value >> 8)
packed = age << 8 | gender << 7 | height
packed = age << 8 + gender << 7 + height
age = packed >> 8 // no mask required
gender = packed >> 7 & ((1 << 1) - 1) // applying mask (for gender it is just 1)
height = packed & ((1 << 7) - 1) // applying mask
packed = (comp1 << 0 * 10) | (comp1 << 1 * 10) | (comp1 << 2 * 10) | (comp1 << 3 * 10)
comp1 = (packed >> 0 * 10) & ((1 << 10) - 1) // 132
comp2 = (packed >> 1 * 10) & ((1 << 10) - 1) // 513
comp3 = (packed >> 2 * 10) & ((1 << 10) - 1) // 151
comp4 = (packed >> 3 * 10) & ((1 << 10) - 1) // 319
SELECT

(@offset := 10) AS `No of bits required for each component`,
(@packed := (132 << 0 * @offset) | 
            (513 << 1 * @offset) | 
            (151 << 2 * @offset) | 
            (319 << 3 * @offset)) AS `Packed value (132.513.151.319)`,

BIN(@packed) AS `Packed value (bin)`,

(@packed >> 0 * @offset) & ((1 << @offset) - 1) `Component 1`,
(@packed >> 1 * @offset) & ((1 << @offset) - 1) `Component 2`,
(@packed >> 2 * @offset) & ((1 << @offset) - 1) `Component 3`,
(@packed >> 3 * @offset) & ((1 << @offset) - 1) `Component 4`;
YES   =    2^0    =    1    =    00000001
NO    =    2^1    =    2    = 00000010
MAYBE =    2^2    =    4    = 00000100
SUM    =    1    +    4    =    5

SUM    =    00000001    +    00000100    =    00000101 
1    &    5    =    1    ( non zero )

2    &    5    =    0    ( zero )

4    &    5    =    4    ( non zero )
1    =    2^0    =    YES
4    =    2^2    =    MAYBE.