Вопрос по unsigned, java – Лучший способ преобразовать целое число со знаком в длинную без знака?

47

Для некоторых хеш-функций в Java было бы хорошо видеть значение как целое число без знака (например, для сравнения с другими реализациями), но Java поддерживает только подписанные типы. Мы можем конвертировать подписанныйint "без знака"long в качестве таких:

public static final int BITS_PER_BYTE = 8;
public static long getUnsignedInt(int x) {
  ByteBuffer buf = ByteBuffer.allocate(Long.SIZE / BITS_PER_BYTE);
  buf.putInt(Integer.SIZE / BITS_PER_BYTE, x);
  return buf.getLong(0);
}
getUnsignedInt(-1); // => 4294967295

Однако это решение кажется излишним для того, что мы действительно делаем. Есть ли более эффективный способ добиться того же?

Ваш Ответ

7   ответов
-4
long abs(int num){
    return num < 0 ? num * -1 : num;
}
пожалуйста, прочитайте о двух дополнениях (en.wikipedia.org/wiki/Two%27s_complement), который описывает, как обычно представлены числа со знаком. Вы не можете просто принять абсолютное значение для решения этой проблемы (tadej.me/twos-complement-and-absolute-values). Stepan Pogosyan
2

другое решение.

public static long getUnsignedInt(int x) {
    if(x > 0) return x;
    long res = (long)(Math.pow(2, 32)) + x;
    return res;
}
Потому что int 32-битный и использовать два дополнения для представления. Вы можете проверить два дополнения в википедии (en.wikipedia.org/wiki/Two's_complement) чтобы узнать больше lmatt
Можете ли вы дать мне ссылку или описание, как эти преобразования работают, я не могу понять это. ManMohan Vyas
Math.pow очень дорогой и рассчитывается каждый раз. По сравнению1l << 32 быстрый и рассчитывается только компилятором (И не нужно долго отбрасывать. Peter Lawrey
-2

public static long getUnsignedInt(int x) { return x & (~0L); // ~ has precedence over & so no real need for brackets }

вместо:

вернуть x & 0xFFFFFFFFL;

В этой ситуации вас не беспокоит, сколько у F маски. Это всегда будет работать!

Это совершенно неправильно. Int повышается до long, а затем вы маскируете его битовой строкой из 64, которая ничего не делает. Следующее печатает -1 вместо 4294967295: int i = -1; длинный j = i & (~ 0L); System.out.println (J); PBJ
да, это плохо, я перепутал 0xFFFFFFFFL с ~ 0L, что очевидно не так okoopat
28

Integer.toUnsignedLong(someInt), что эквивалентно@ Mysticial's answer.

7

Вы можете использовать функцию как

public static long getUnsignedInt(int x) {
    return x & (-1L >>> 32);
}

однако в большинстве случаев вам не нужно это делать. Вместо этого вы можете использовать обходные пути. например

public static boolean unsignedEquals(int a, int b) {
    return a == b;
}

Дополнительные примеры обходных путей для использования значений без знака.Утилита без знака

getUnsignedInt, кажется, работает как есть.>>> правильно.>> вызывает расширение знака, и -1L, смещенное вправо с расширением знака, любая величина всегда приводит к значению со всеми единицами. Macil
Ваша функция getUnsignedInt не работает. Я допустил серьезную ошибку в своей программе, поскольку не проверял ее. : (( user2707175
@ user2707175 изменить>>> в>> и это должно работать Jeff Jones
85

Что-то вроде этого?

int x = -1;
long y = x & 0x00000000ffffffffL;

Или я что-то упустил?

public static long getUnsignedInt(int x) {
    return x & 0x00000000ffffffffL;
}
Мех, так бывает. Особенно в C ++, где есть много способов сделать все. Mysticial
@Paranaix Я думаю, это тоже сработает. Прошло много времени с тех пор, как я написал этот ответ, поэтому я думаю, что причина, по которой я дополнял нулями, была по привычке, поскольку я в основном использую C ++, а правила целочисленного продвижения там более сложны для типов со знаком / без знака. Mysticial
+1 верно. Нет, это я что-то упустил - я запутался в расширении конверсий и упустил из виду простой подход =) maerics
Спасибо, столкнулся с этой проблемой, используя Murmur Hashes. Richard Clayton
Было быx & 0xFFFFFFFFL работать тоже? Sebastian Hoffmann
16

гуайява обеспечиваетUnsignedInts.toLong(int)... а также множество других утилит на целых числах без знака.

Похожие вопросы