在向上转换或转换Java时抑制符号扩展

我觉得这是一个相当微不足道的问题,但我很难过。 在我的应用程序中,我使用一对int在一个查找表中键入内容。 我认为将两个int连接成一个long更容易,而使用single long作为键。 来自C背景,我希望这样的东西能起作用:

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

我试图用Java复制这个尝试让我感到沮丧。 特别是,因为没有无符号整数类型,我似乎无法避免b的自动符号扩展(a左移以使其无关紧要)。 我尝试过使用b & 0x00000000FFFFFFFF但令人惊讶的是没有效果。 我也尝试了相当丑陋的(long)b <> 32 ,但它似乎被编译器优化了。

我希望严格使用基元的位操作,但我开始怀疑是否需要使用某种缓冲对象来实现这一点。

我总是使用我的实用程序类

 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; } 

对于任何int x, y (否定与否)

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

持有任何long z

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

也持有。

我不时这样做 – 我在XY坐标中存储两个整数。 因为我知道我的范围永远不会超过10亿,所以我会做以下事情:

 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 }; }