将Java int的底部16位作为带符号的16位值

时间:2009-07-03 17:00:47

标签: java bit-manipulation math

嗯。考虑一下这个程序,它的目标是找出获得整数的最后16位的最佳方法,作为有符号整数。

public class SignExtend16 {
    public static int get16Bits(int x)
    { 
        return (x & 0xffff) - ((x & 0x8000) << 1);
    }

    public static int get16Bits0(int x)
    { 
        return (int)(short)(x);
    }    

    public static void main(String[] args)
    {
        for (String s : args)
        {
            int x = Integer.parseInt(s);
            System.out.printf("%08x => %08x, %08x\n",
               x, get16Bits0(x), get16Bits(x));
        }
    }
}

我打算在get16Bits0中使用代码,但是我在Eclipse的编译器中收到了“从必须强制转换为int”的警告,这让我很怀疑,认为编译器可以优化我的“不必要的演员”。当我使用Eclipse的编译器在我的机器上运行它时,我得到两个函数的相同结果,这些函数的行为与我的预期一致(测试参数:1 1111 11111 33333 66666 99999)。这是否意味着我可以使用get16Bits0? (对未来的代码维护者提出适当的警告)我一直认为JRE和编译器行为在算术上都与机器无关,但这种情况在某种程度上测试了我的信念。

4 个答案:

答案 0 :(得分:5)

由于数字转换是隐式友好的,我认为你得到警告的唯一原因是编译器总是在返回时将转换为int,使你的显式转换为多余。

答案 1 :(得分:5)

好吧,首先警告是正确的,因为你总是可以通过算术转换“向上”移动。只有另一种方式需要转换,因为您可能会丢失数据(或浮点数的精度)。

当你从int减少到short时,你必须通过使用强制转换表明它是故意的。但是当你将短值转换回int时没有危险,它会自动发生。

所以,你需要的只是

return (short) x;

答案 2 :(得分:4)

如果你想避免演员表,你可以这样做:

(x << 16) >> 16

此技术也适用于不同数量的位。说底15:

(x <&lt; 17)&gt; 17

更改&gt;&gt;到&gt;&gt;&gt;对于未签名的版本。

答案 3 :(得分:0)

是的,get16Bits0应该可以工作,只需在函数前面添加一个suppressWarning元标记。