位打包在Java中导致错误的值

时间:2017-03-28 20:11:38

标签: java byte bit

我在Java中有以下方法将一组四个字节的整数表示组合成一个long。

public static long addBytesToInt(int x1, int x2, int x3, int x4) {
    return ((x4 << 24) | (x3 << 16) | (x2 << 8) | (x1 & 0xFF));
}

但问题是如果我用例如以下值来调用它:

//1111 1111 0000 1111 0011 1100 0000 0011 = 4279188483    
addBytesToInt(3, 60, 15, 255);

它会返回错误的值。 我不得不更改为以下代码,以使其按预期工作,我无法弄清楚原因:

public static long addBytesToInt(int x1, int x2, int x3, int x4) {
    long l = 0;

    l = (l << 8) + x4;
    l = (l << 8) + x3;
    l = (l << 8) + x2;
    l = (l << 8) + x1;

    return l;
}

1 个答案:

答案 0 :(得分:1)

((x4 << 24) | (x3 << 16) | (x2 << 8) | (x1 & 0xFF))的问题与操作数的类型有关。由于x1 - x4都具有类型int,因此每个班次操作的结果也具有类型int。因此,每个算术或操作的结果也具有类型int。当x4的值大于127时,最终int结果的符号位已设置,因此表示负数。当该数字转换为long以进行返回时,将保留(负)值。

由于生成的long值的所有低32位都设置正确,因此解决问题的最简单方法是屏蔽32个高位。即,对当前结果应用& 0xffffffffL操作。

同样不适用于您的工作替代方案。由于变量l具有类型long,因此每个操作都会生成类型long的结果。不会发生溢出,并且永远不会设置符号位。

相关问题