如何将字节数组转换为其数值(Java)?


89

我有一个8字节的数组,我想将其转换为相应的数值。

例如

byte[] by = new byte[8];  // the byte array is stored in 'by'

// CONVERSION OPERATION
// return the numeric value

我想要一种可以执行上述转换操作的方法。


4
您所说的“数值”是什么意思?字节代表二进制的整数(长整数)还是浮点数(双精度整数)?它们是数字的字符串表示形式吗?还是另一个代表?
starblue


注意:TacB0sS的链接是我实际上正在寻找的-正向和反向转换。
杰伊·泰勒

new BigInteger(by).longValue()
罗恩侯爵,

Answers:


106

假设第一个字节是最低有效字节:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value += ((long) by[i] & 0xffL) << (8 * i);
}

第一个字节是最高位,然后略有不同:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value = (value << 8) + (by[i] & 0xff);
}

如果您有8个以上的字节,请用BigInteger替换long 。

感谢Aaron Digulla纠正了我的错误。


8
-1个字节是带符号的值!并用shift(<<)替换pow()!“值=(值<< 8)+(by [i]&0xff)”
Aaron Digulla 09年

移位运算符(<<)是否具有从右到左的优先级?上面的代码如何工作?对我来说一切正常。只想知道工作原理。提前
感谢

@Mnementh:移位运算符(<<)是否具有从右到左的优先级?上面的代码如何工作?对我来说一切正常。只想知道工作原理。提前
感谢

5
万一其他人遇到与我相同的问题,在第一个示例中,必须将by [i]强制转换为long,否则它仅适用于小于2 ^ 32的值。也就是说,value += ((long)by[i] & 0xffL) << (8 * i);
路加福音

115

可以使用Buffer作为的一部分提供的。java.nio包的来执行转换。

在此,源byte[]数组的长度为8,它的大小与一个long值相对应。

首先, byte[]数组包装在中ByteBuffer,然后ByteBuffer.getLong调用方法以获取long值:

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 0, 0, 0, 0, 4});
long l = bb.getLong();

System.out.println(l);

结果

4

我要感谢dfa ByteBuffer.getLong在评论中指出该方法。


尽管在这种情况下可能不适用,但Buffer通过查看具有多个值的数组可以带来s 的魅力。

例如,如果我们有一个8字节的数组,并且希望将其视为两个int值,则可以将byte[]数组包装为ByteBuffer,将其视为IntBuffer然后通过IntBuffer.get以下方式获取值:

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 1, 0, 0, 0, 4});
IntBuffer ib = bb.asIntBuffer();
int i0 = ib.get(0);
int i1 = ib.get(1);

System.out.println(i0);
System.out.println(i1);

结果:

1
4

ByteBuffer.wrap(new byte [] {0,0,0,1,0,0,0,4})。getLong()怎么办?此方法应读取下一个8个字节并将其转换为长
整数

@dfa:感谢您指出这一点,它似乎确实有效-我将编辑答案。:)
coobird

16

如果这是一个8字节的数值,则可以尝试:

BigInteger n = new BigInteger(byteArray);

如果这是UTF-8字符缓冲区,则可以尝试:

BigInteger n = new BigInteger(new String(byteArray, "UTF-8"));

如果它在第一个代码段之后立即结束,或者如果它包含一些将字符串转换为“数字值”的代码,我将对此答案投赞成票。照原样,您的答案的后半部分似乎毫无道理。
劳伦斯·贡萨尔维斯(Lawrence Gonsalves),2009年

首先,我的意思不是我的意思,而是我改变了答案
文森特·罗伯特


9

您也可以将BigInteger用于可变长度的字节。您可以根据需要将其转换为Long,Integer或Short。

new BigInteger(bytes).intValue();

或表示极性:

new BigInteger(1, bytes).intValue();


1

数组中的每个单元均被视为unsigned int:

private int unsignedIntFromByteArray(byte[] bytes) {
int res = 0;
if (bytes == null)
    return res;


for (int i=0;i<bytes.length;i++){
    res = res | ((bytes[i] & 0xff) << i*8);
}
return res;
}

请注意,我需要使用0xFFL,否则当我打印Long.toHexString(l)时,从int 0xFF到long的强制转换会设置很多错误的1位。
路加福音

您需要使用0xFFL,否则将获得符号扩展名。
灰色,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.