位打包导致 Java 中的错误值

Bit packing results in wrong value in Java

我有以下方法 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);

它会 return 错误的值。 我必须更改为以下代码才能按预期工作,但我不知道为什么:

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;
}

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

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

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