39

I want to store two ints in a long (instead of having to create a new Point object every time).

Currently, I tried this. It's not working, but I don't know what is wrong with it:

// x and y are ints
long l = x;
l = (l << 32) | y;

And I'm getting the int values like so:

x = (int) l >> 32;
y = (int) l & 0xffffffff;

3 Answers 3

76

y is getting sign-extended in the first snippet, which would overwrite x with -1 whenever y < 0.

In the second snippet, the cast to int is done before the shift, so x actually gets the value of y.

long l = (((long)x) << 32) | (y & 0xffffffffL);
int x = (int)(l >> 32);
int y = (int)l;
Sign up to request clarification or add additional context in comments.

2 Comments

Ah, that makes sense. One question I have is whether it matters if you bitmask using the long 0xffffffffL or the int 0xffffffff.
@LanguagesNamedAfterCofee yes it matters, if you mask with 0xffffffff (without the L) then it's just an int, so the & is a no-op and y still gets sign extended.
16

Here is another option which uses a bytebuffer instead of bitwise operators. Speed-wise, it is slower, about 1/5 the speed, but it is much easier to see what is happening:

long l = ByteBuffer.allocate(8).putInt(x).putInt(y).getLong(0);
//
ByteBuffer buffer = ByteBuffer.allocate(8).putLong(l);
x = buffer.getInt(0);
y = buffer.getInt(4);

2 Comments

Java 8 has Long.BYTES, even more clear than the magic number 8.
y = buffer.getInt(4); - the argument is the byte offset, so it's 4.
-1

If you want to store two Float values that are (32-bits) as a single Long value (64-bits). You can convert the bits from the float value into bits for integer value and then to the same as the previous answers.

// first method using floatToIntBits 
long method1(float x, float y) {

    int xInt = java.lang.Float.floatToIntBits(x);
    int yInt = java.lang.Float.floatToIntBits(y);
    
    return (((long)xInt) << 32) | (yInt & 0xffffffffL);
}

// second method using ByteBuffer
long method2(float x, float y) {
    return ByteBuffer.allocate(java.lang.Long.BYTES).putFloat(x).putFloat(y).getLong(0);
}
 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.