2
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]);

}

我对此的期望是这样的;

s0二进制是b0000_1111_1111_1111

s1二进制是b0000_0000_0000_1101

sh然后变成b1101_1111_1111_1111

前面1是符号,其余 15 位给出sh十进制值,-24575但这不是我输出到控制台的值(即-8193)。

我怎么了?

4

3 回答 3

6

b1101_1111_1111_1111 是-8193,它正在输出正确答案。可能想重温你的 2s 补充。

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

于 2012-05-25T19:06:39.487 回答
6

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

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

  1. 0010_0000_0000_0000
  2. 0010_0000_0000_0001

这是8193,这正是打印出来的。

于 2012-05-25T19:07:31.497 回答
2

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

于 2012-05-25T19:08:34.457 回答