开发者

Wrapping 4 integers in a 64 bit long - java bitwise

开发者 https://www.devze.com 2022-12-21 18:34 出处:网络
Alright, so I have 4 integers I want to wrap in a long. The 4 integers all contains 3 values, positioned in the first 2 bytes:

Alright, so I have 4 integers I want to wrap in a long. The 4 integers all contains 3 values, positioned in the first 2 bytes:

 +--------+--------+
 |xxpppppp|hdcsrrrr|
 +--------+--------+

{pppppp} represents one value, {hdcs} represents the second and {rrrr} the last.

I want to pack 4 of these integers, in a long. I've tried the following:

ordinal = (c1.ordinal() << (14*3) | c2.ordinal() << (14*2) | c3.ordinal() << 14 | c4.ordinal());

where c1.ordinal()...c4.ordinal() is the integers to wrap.

This does not seem to work if I run a test. Lets say I want to look up the values of the last integer in the long, c4.ordinal(), where {pppppp} = 41, {hdcs} = 8 and {rrrr} = 14, I get the following results:

System.out.println(c4.ordinal() & 0xf); //Prints 14
System.out.println(hand.ordinal() & 0xf); // Prints 14 - correct

System.out.println(c4.ordinal() >> 4 & 0xf); // Prints 8
System.out.println(hand.ordinal() >> 4 & 0xf); // Prints 8 - correct

System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() &g开发者_运维百科t;> 8 & 0x3f); // Prints 61 - NOT correct!

Now, the following is weird to me. If I remove the first two integers, and only wrap the last two, like this:

ordinal = (c3.ordinal() << 14 | c4.ordinal());

And run the same test, I get the correct result:

System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() >> 8 & 0x3f); // Prints 41 - correct!

I have no idea whats wrong. And it does not make any sense to me, that I get the correct answer if I remove the first two integers. I'm starting to thing this might have to do with the long datatype, but I've not found anything yet, that supports this theory.


Even though you are assigning the result to a long, all of the operations are performed with int values, and so the high-order bits are lost. Force "promotion" to a long by explicitly widening the values to a long.

long ordinal = (long) c1.ordinal() << (14*3) | 
               (long) c2.ordinal() << (14*2) | 
               (long) c3.ordinal() <<    14  | 
               (long) c4.ordinal();

Also, unless you are positive that the top two bits of each value are zero, you could run into other problems. You may wish to mask these off for safety's sake:

long ordinal = (c1.ordinal() & 0x3FFFL) << (14*3) | 
               (c2.ordinal() & 0x3FFFL) << (14*2) | 
               (c3.ordinal() & 0x3FFFL) <<    14  | 
               (c4.ordinal() & 0x3FFFL);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号