将4个字节打包成int

时间:2011-05-24 22:20:35

标签: java bit-manipulation

  

可能重复:
  Convert 4 bytes to int

我正在尝试使用此处找到的一些解决方案将4个字节打包到int中,但它似乎不适用于我的一个测试。

这是我正在使用的代码:

public static int pack(int c1, int c2, int c3, int c4)
{
    return (c1 << 24) | (c2 << 16) | (c3 << 8) | (c4);
}

现在,当我在像0x34,0x68,0x77和0x23这样简单的东西上使用它时,我得到了我所期望的:0x34687723。但是当我在0xBA,0xAD,0xBE和0xEF上使用它时,我得到了一些东西。有谁看到问题可能是什么?

修改

上面的代码能够给我我想要的东西,我在下面提到的“错误值”只是以十进制形式表示0xBAADBEEF的另一种方式。

4 个答案:

答案 0 :(得分:9)

您在pack方法中的代码是正确的并保留所有位但由于结果存储在signed int中,当您尝试将其作为int打印或进行算术计算或与其进行比较时,会得到错误的结果。

int result = pack( c1, c2, c3, c4 );
System.out.println( "result=" + Long.toHexString( result & 0xffffffffL );

这将int打印为unsigned int。

答案 1 :(得分:6)

存储在Java int中的数字只能表示高达0x7fffffff的正值(2147483647,Integer.MAX_VALUE),因为它是带符号的类型(与所有Java数字类型一样),并且在内部表示中,最高有效位用作符号位。

要保留大于您需要使用long的正数值:

public static long pack(int c1, int c2, int c3, int c4)
{
        return ((c1 << 24) | (c2 << 16) | (c3 << 8) | (c4)) & 0xffffffffL;
}

注意最后的显式long掩码操作,这是确保符号扩展不会导致负整数结果变为负长的必要条件。

答案 2 :(得分:0)

签署扩展名。在Java中,int是签名的,因此0xBA&lt;&lt; 24会变得不快乐。我建议你打包到long的最后四个字节。

long temp =
   ((0xFF & c1) << 24) | ((0xFF & c2) << 16) | ((0xFF & c3) << 8) | (0xFF   & c4);

return (int)(temp & 0x0FFFFFFFFL);

答案 3 :(得分:-1)

你得到负数吗?也许unsigned int或更长的int可以更好地工作。