如何在Java中将字节转换为long?

Jot*_*ham 5 java

我正在从硬件设备读取8个字节的数据.我需要将它们转换为数值.我想我想将它们转换为长度,因为它应该适合8个字节.我对Java和低级数据类型操作不是很熟悉.我似乎有两个问题(除了几乎没有相关硬件的文档),字节期望是无符号的,所以我不能进行直接整数转换.我不确定它们是什么字节序.

任何意见,将不胜感激.


结束了这个(取自一些源代码,我可能应该在一周前阅读):

public static final long toLong (byte[] byteArray, int offset, int len)
{
   long val = 0;
   len = Math.min(len, 8);
   for (int i = (len - 1); i >= 0; i--)
   {
      val <<= 8;
      val |= (byteArray [offset + i] & 0x00FF);
   }
   return val;
}
Run Code Online (Sandbox Code Playgroud)

eri*_*son 12

根据数据的字节顺序移动字节非常简单.long但是,数据类型有一个小技巧,因为对整数类型int或更小类型的二进制操作会将操作数提升为int.对于大于31位的左移,这将导致零,因为所有位都已移出int范围.

因此,long通过long在计算中包含操作数来强制升级.下面,我通过使用值0xFF L屏蔽每个字节来执行此操作,该值为a long,强制结果为a long.

byte[] buf = new byte[8];
/* Fill buf somehow... */
long l = ((buf[0] & 0xFFL) << 56) |
         ((buf[1] & 0xFFL) << 48) |
         ((buf[2] & 0xFFL) << 40) |
         ((buf[3] & 0xFFL) << 32) |
         ((buf[4] & 0xFFL) << 24) |
         ((buf[5] & 0xFFL) << 16) |
         ((buf[6] & 0xFFL) <<  8) |
         ((buf[7] & 0xFFL) <<  0) ;
Run Code Online (Sandbox Code Playgroud)


Bos*_*one 6

Byte#longValue()应该这样做

如果没有(感谢源示例),您可以使用 java.nio.ByteBuffer 例如

 public static long toLong(byte[] b) {
    ByteBuffer bb = ByteBuffer.allocate(b.length);
    bb.put(b);
    return bb.getLong();
}
Run Code Online (Sandbox Code Playgroud)

最初的订单是 BIG_ENDIAN 你可以在这里了解更多

  • 除非我在调用“getLong()”之前调用“bb.flip();”,否则我会收到“BufferUnderflowException” (2认同)

Cor*_*chi 6

ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.getLong();
Run Code Online (Sandbox Code Playgroud)


Gun*_*r47 5

我相信你可以从使用java.nio中受益.这是你如何在一个长的存储8个字节:

// Byte Array TO Long
public static long batol(byte[] buff) {
    return batol(buff, false);
}

public static long batol(byte[] buff, boolean littleEndian) {
    assert(buff.length == 8);
    ByteBuffer bb = ByteBuffer.wrap(buff);
    if (littleEndian) bb.order(ByteOrder.LITTLE_ENDIAN);
    return bb.getLong();
}
Run Code Online (Sandbox Code Playgroud)

当然,生成的longs将具有签名表示,但它们将具有与源数据相同的二进制值.对于64位+无符号表示和算术,您需要使用BigInteger.以下是如何将存储在long中的"unsigned"数据转换为正确的BigInteger:

// "Unsigned" Long TO Big Integer
public static BigInteger ultobi(long ul) {
    byte[] buff = new byte[8];
    ByteBuffer.wrap(buff).asLongBuffer().put(ul);
    return new BigInteger(+1, buff);
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*ack 2

对于字节顺序,用一些您知道的数字进行测试,然后您将使用字节移位将它们移至长字节。

您可能会发现这是一个起点。 http://www.janeg.ca/scjp/oper/shift.html

困难在于,根据字节顺序会改变你的操作方式,但你将移位 24、16、8,然后添加最后一位,基本上,如果执行 32 位,但你会更长,所以只需进行额外的移位。