可能重复:
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的另一种方式。
答案 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可以更好地工作。