开发者

Suppressing sign-extension when upcasting or shifting in Java

开发者 https://www.devze.com 2023-02-14 12:14 出处:网络
I have a feeling this is a rather trivial question, but I\'m stumped. In my application I\'m keying things in a lookup table with a pair of ints. I thought it would be easier to concatenate the two in

I have a feeling this is a rather trivial question, but I'm stumped. In my application I'm keying things in a lookup table with a pair of ints. I thought it would be easier to concatenate the two ints into one long and use the single long as a key instead. Coming from a C background, I was hoping something like this would work:

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

My attempts to replicate this in Java have frustrated me. In particular, because there are no unsigned integral types, I can't seem t开发者_JAVA百科o avoid the automatic sign-extension of b (a gets left-shifted so its irrelevant). I've tried using b & 0x00000000FFFFFFFF but it surprisingly has no effect. I also tried the rather ugly (long)b << 32 >> 32, but it seemed to be optimized out by the compiler.

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


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

holds and for any long z

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

holds, too.


I do this from time to time - I store two ints in a long for my X Y coordinates. Because I know 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 };
}
0

精彩评论

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

关注公众号