我觉得这是一个相当微不足道的问题,但我很难过。在我的应用程序中,我正在使用一对整数在查找表中键入内容。我认为将两个int连接成一个long更容易,而使用single long作为键。来自C背景,我希望这样的东西能起作用:
int a, b;
long l = (long)a << 32 | b;
我试图用Java复制这个尝试让我感到沮丧。特别是,因为没有无符号整数类型,我似乎无法避免b的自动符号扩展(a左移以使其无关紧要)。我尝试使用b & 0x00000000FFFFFFFF
,但令人惊讶的是没有效果。我也尝试了相当丑陋的(long)b << 32 >> 32
,但它似乎被编译器优化了。
我希望严格使用基元的位操作,但是我开始怀疑是否需要使用某种缓冲对象来实现这一点。
答案 0 :(得分:16)
我总是使用我的实用程序类
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
也有。
答案 1 :(得分:1)
我不时这样做 - 我在X Y坐标中存储了两个整数。因为我知道我的范围永远不会超过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 };
}