Suppressing character expansion when raising or shifting in Java

I have a feeling that this is a pretty trivial question, but I'm at a dead end. In my application, I am manipulating the lookup table with an int pair. I thought it would be easier to combine the two ints into one long and use one long as a key instead. Based on background C, I was hoping this would work:

int a, b; long l = (long)a << 32 | b; 

My attempts to repeat this in Java upset me. In particular, since there are no unsigned integral types, I cannot avoid automatically expanding the sign of b (a has a left shift, so it doesn't matter). I tried using b & 0x00000000FFFFFFFF , but this unexpectedly has no effect. I also tried the rather ugly (long)b << 32 >> 32 , but it seemed to be optimized by the compiler.

I was hoping to do it strictly using bit manipulation with primitives, but I'm starting to wonder if I need to use some kind of buffer object for this.

+7
java
source share
2 answers

I always use my utility class with

 public static long compose(int hi, int lo) { return (((long) hi << 32) + unsigned(lo)); } public static long unsigned(int x) { return x & 0xFFFFFFFFL; } public static int high(long x) { return (int) (x>>32); } public static int low(long x) { return (int) x; } 

For any int x, y (negative or not)

 high(compose(x, y)) == x low(compose(x, y)) == y 

and for any long z

 compose(high(z), low(z)) == z 

also.

+16
source share

I do this from time to time - I keep two ints in long for my XY coordinates. Since I know that my range will never be more than 1 billion, I do the following:

 private Long keyFor(int x, int y) { int kx = x + 1000000000; int ky = y + 1000000000; return (long)kx | (long)ky << 32; } private Long keyFor(int[] c) { return keyFor(c[0],c[1]); } private int[] coordsFor(long k) { int x = (int)(k & 0xFFFFFFFF) - 1000000000; int y = (int)((k >>> 32) & 0xFFFFFFFF) - 1000000000; return new int[] { x,y }; } 
+1
source share

All Articles