Java хранит два целых числа в длинном

Я хочу хранить два целых числа в длинном (вместо того, чтобы каждый раз создавать новый объект Point).

В настоящее время я попробовал это. Это не работает, но я не знаю, что с ним не так:

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

И я получаю значения int следующим образом:

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

person LanguagesNamedAfterCofee    schedule 07.10.2012    source источник


Ответы (3)


y расширяется знаком в первом фрагменте, который перезаписывает x на -1 всякий раз, когда y < 0.

Во втором фрагменте приведение к int выполняется до сдвига, поэтому x фактически получает значение y.

long l = (((long)x) << 32) | (y & 0xffffffffL);
int x = (int)(l >> 32);
int y = (int)l;
person harold    schedule 07.10.2012
comment
А, это имеет смысл. У меня есть один вопрос: имеет ли значение, используете ли вы битовую маску, используя long 0xffffffffL или int 0xffffffff. - person LanguagesNamedAfterCofee; 08.10.2012
comment
@LanguagesNamedAfterCofee да, это имеет значение, если вы маскируете с помощью 0xffffffff (без буквы L), то это просто целое число, поэтому & не используется, а y все еще получает расширенный знак. - person harold; 08.10.2012

Вот еще один вариант, который использует байтовый буфер вместо побитовых операторов. По скорости он медленнее, примерно в 1/5 раза быстрее, но гораздо легче увидеть, что происходит:

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);
person Mingwei Samuel    schedule 06.08.2014
comment
В Java 8 есть Long.BYTES, даже более понятное, чем магическое число 8. - person Maarten Bodewes; 29.09.2018
comment
y = buffer.getInt(4); — аргумент представляет собой смещение в байтах, поэтому оно равно 4. - person Luke; 29.01.2019

Если вы хотите сохранить два значения с плавающей запятой (32 бита) как одно длинное значение (64 бита). Вы можете преобразовать биты из значения с плавающей запятой в биты для целочисленного значения, а затем в то же самое, что и в предыдущих ответах.

// 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);
}
 
person slaviboy    schedule 28.12.2020