Java - Bitwise操作没有达到预期的效果

时间:2012-05-25 18:58:09

标签: java binary bit-manipulation

private void test2() {
    // This test takes two shorts and sticks them together in a
    // 4 bit 12 bit configuration within a short, it then breaks
    // them apart again to see if it worked!
    short s0 = 4095;
    short s1 = 13;

    short sh = (short)((s1 << 12) | s0);

    System.out.println(sh);

    short[] sa = new short[] {
        (short)(sh & 0xFFF),
        (short)((sh >>> 12) & 0xF)
    };

    System.out.println(sa[0]);
    System.out.println(sa[1]);

}

我对此的期望是这个;

二进制文件中的

s0b0000_1111_1111_1111

二进制文件中的

s1b0000_0000_0000_1101

sh然后变为b1101_1111_1111_1111

前面的1是符号,剩下的15位给出了值,因此sh的十进制为-24575,但这不是我输出到控制台的内容(即{ {1}})。

我出错了什么?

3 个答案:

答案 0 :(得分:6)

b1101_1111_1111_1111是-8193,正在输出正确的答案。可能想要更新你的2s补充。

http://en.wikipedia.org/wiki/Two%27s_complement

答案 1 :(得分:6)

结果实际上是正确的。二进制数表示在所谓的2s补码中。因此,要计算负数的绝对值,您不仅要删除符号位并查看剩余的内容。相反,你这样做: 1.翻转所有位,包括符号位 2.加1

在你的情况下,这意味着你得到了

  1. 0010_0000_0000_0000
  2. 0010_0000_0000_0001
  3. 这是8193,这正是打印出来的。

答案 2 :(得分:2)

使用的表示不是符号模数,而是2补码。因此,为了知道哪个数字由以1开头的位序列表示,必须减1然后反转。在你的情况下,你将得到1101_1111_1111_1110倒置,这将给出0010_0000_0000_0001,这是非常好的8193.因此,没有任何问题 - 你只是混淆了内部表示机制。