Преобразование 32-битного целого числа без знака (big endian) в long и обратно

У меня есть байт [4], который содержит 32-битное целое число без знака (в порядке прямого байта), и мне нужно преобразовать его в long (поскольку int не может содержать беззнаковое число).

Кроме того, как мне сделать это наоборот (т.е. от long, содержащего 32-битное целое число без знака, до байта [4])?


person Aviram    schedule 24.03.2012    source источник
comment
откуда берется массив байтов?   -  person Raffaele    schedule 25.03.2012


Ответы (3)


Похоже, работа для ByteBuffer.

В некотором роде

public static void main(String[] args) {
    byte[] payload = toArray(-1991249);
    int number = fromArray(payload);
    System.out.println(number);
}

public static  int fromArray(byte[] payload){
    ByteBuffer buffer = ByteBuffer.wrap(payload);
    buffer.order(ByteOrder.BIG_ENDIAN);
    return buffer.getInt();
}

public static byte[] toArray(int value){
    ByteBuffer buffer = ByteBuffer.allocate(4);
    buffer.order(ByteOrder.BIG_ENDIAN);
    buffer.putInt(value);
    buffer.flip();
    return buffer.array();
}
person Edwin Dalorzo    schedule 24.03.2012
comment
Поправьте меня, если я ошибаюсь, но если я сделаю int value = buffer.getInt();, тогда int может не содержать всего числа (если оно беззнаковое и не подписанное). - person Aviram; 25.03.2012
comment
@Aviram Целое число в Java - 32-битное (4 байта), пока ваш ByteBuffer имеет длину 4 байта, я не понимаю, почему должна быть проблема. Я улучшил свой ответ и проверил его с положительными и отрицательными результатами, и пока он работает отлично. Могу я что-то упустить? Если вы собираетесь использовать целые числа без знака, используйте длинные, а не целые числа, потому что целые числа в Java подписаны. - person Edwin Dalorzo; 25.03.2012
comment
Вы можете использовать return buffer.getInt() & 0xFFFFFFFFL;, так как вы всегда будете получать беззнаковое значение. ByteBuffer по умолчанию - BIG_ENDIAN. Вам не нужно звонить flip(), чтобы использовать array() - person Peter Lawrey; 25.03.2012

Вы можете использовать ByteBuffer или сделать это по старинке:

long result = 0x00FF & byteData[0];
result <<= 8;
result += 0x00FF & byteData[1];
result <<= 8;
result += 0x00FF & byteData[2];
result <<= 8;
result += 0x00FF & byteData[3];
person Hot Licks    schedule 24.03.2012

В Guava есть полезные классы для работы с числовыми значениями без знака.

http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/primitives/UnsignedInts.html#toLong(int)

person Sam Barnum    schedule 24.03.2012
comment
Хороший момент, это чрезмерно просто использовать метод & 0xFFFFFFFFL, описанный Питером Лоури выше в одном комментарии к этому вопросу. - person Emmanuel Touzery; 08.01.2013
comment
Почему toLong (Integer.MIN_VALUE) не работает? и вернуть отрицательный длинный ideone.com/cERLo1 - person gavioto; 17.07.2014