在Java中将C< uint32转换为int的正确方法

时间:2014-03-03 09:04:05

标签: java c binary type-conversion unsigned-integer

我正在构建一个由多个组件组成的项目,这些组件使用套接字在字节数组中相互通信。问题是一个组件是用C编写的,它支持Unsigned原语类型,而其他组件是用Java编写的,不支持Unsigned类型。我正在尝试开发对Java中的Unsigned类型的支持。我是Java新手。任何人都可以告诉我从字节数组解码uint32和uint64的正确方法。

我使用以下函数转换int32和int64

public static int int32Converter(byte b[], int start) {
    return ((b[start] << 24) & 0xff000000 |(b[start + 1] << 16) & 0xff0000
            | (b[start + 2] << 8) & 0xff00 | (b[start + 3]) & 0xff);
}
public static long int64Converter(byte buf[], int start) {
    return ((buf[start] & 0xFFL) << 56) | ((buf[start + 1] & 0xFFL) << 48)
            | ((buf[start + 2] & 0xFFL) << 40)
            | ((buf[start + 3] & 0xFFL) << 32)
            | ((buf[start + 4] & 0xFFL) << 24)
            | ((buf[start + 5] & 0xFFL) << 16)
            | ((buf[start + 6] & 0xFFL) << 8)
            | ((buf[start + 7] & 0xFFL) << 0);
}

谢谢!

3 个答案:

答案 0 :(得分:3)

你无法完全“转换”它们。您发现处理无符号值的最接近的是Guava的UnsignedInteger及其实用程序类UnsignedInts。字节,短路和长信也是一样的。

请注意您的代码,不要手写这些东西,使用ByteBuffer

public static int bytesToInt(final byte[] array, final int start)
{
     final ByteBuffer buf = ByteBuffer.wrap(array); // big endian by default
     buf.position(start);
     buf.put(array);
     return buf.position(start).getInt();
}

将Guava用于unsigned int:

public static UnsignedInteger bytesToUnsignedInt(final byte[] array, final int start)
{
         return UnsignedInteger.fromIntBits(bytesToInt(array, start);
}

但是,我怀疑UnsignedInts确实是你想要的。 (为了比较,打印出来等)

答案 1 :(得分:0)

此代码将数组中的字节复制到int中。索引0(值1)处的字节是LSB。索引3(值15)是MSB:

byte[] bytes = { 1, 3, 7, 15 };
int result = 0; 
for (int i = 0 ; i < bytes.length ; i++) { 
    result |= bytes[i]<<(i*8); 
}
System.out.println(Integer.toBinaryString(result));

打印:

1111000001110000001100000001

如果你将它改为long并给它一个更长的字节数组,并且你将Integer.toBinaryString()从Long更改为1,那么它也可以工作很长时间。

从现在开始,你永远不应该将你的long / int作为常规十进制值打印到屏幕上。当你需要与眼睛比较时,打印它的二进制或十六进制值; Long.toHexString(长)。

答案 2 :(得分:-1)

如果uint32的值永远不会超过2 ^ 31,那么您可以将它们存储在Java int中。如果没有,那么你需要一个java Long。

对于uint64,如果值永远不会超过2 ^ 63那么你将能够使用long,否则你将需要BigInteger。

在任何一种情况下,如果您移植的算法依赖于换行(即值溢出整数并返回0),那么您将需要添加自己的手动逻辑来处理这些场景。