概念[来自wikipedia]
**原码(True form)**:一个二进制数左边加上符号位后所得到的码,且当二进制数大于0时,符号位为0;二进制数小于0时,符号位为1;二进制数等于0时,符号位可以为0或1(+0/-0)
反码(One’s complement):一种在计算机中数的机器码表示。对于单个数值(二进制的0和1)而言,对其进行取反操作就是将0变为1,1变为0
**补码(2’s complement)**:一种用二进制表示有号数的方法,也是一种将数字的正负号变号的方式,主要优点是 不需因为数字的正负而使用不同的计算方式
计算
正数:原码、反码、补码相同
负数:反码 — 符号位不变化,其余位数取反,补码 — 符号位不变化,其余各位原码取反+1, 即 反码+1
测试
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Test public void byteTest() { reverse(0); reverse(6); reverse(-6); reverse(128); reverse(-128); reverse(1280); reverse(-1280); }
private Integer reverse(Integer a) { System.out.printf("%5d\t%32s\t%5d\t%32s\t%5d\t%32s%n", a, Integer.toBinaryString(a), ~a, Integer.toBinaryString((~a)), ~a + 1, Integer.toBinaryString((~a + 1))); return ~a + 1; }
|
结果
1 2 3 4 5 6 7
| 0 0 -1 11111111111111111111111111111111 0 0 6 110 -7 11111111111111111111111111111001 -6 11111111111111111111111111111010 -6 11111111111111111111111111111010 5 101 6 110 128 10000000 -129 11111111111111111111111101111111 -128 11111111111111111111111110000000 -128 11111111111111111111111110000000 127 1111111 128 10000000 1280 10100000000 -1281 11111111111111111111101011111111 -1280 11111111111111111111101100000000 -1280 11111111111111111111101100000000 1279 10011111111 1280 10100000000
|
可以看出:
对一个数字直接取反,并不是其相反数,需要+1
[+0]原码=0000 0000, [-0]原码=1000 0000
[+0]反码=0000 0000, [-0]反码=1111 1111
[+0]补码=0000 0000, [-0]补码=0000 0000