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

时间:2011-02-28 21:24:37

标签: java

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

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

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

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

2 个答案:

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