反码,没有用途;补码,有把减法转换成加法的用途。
----
日常生活中,大家都知道,把时针倒拨20分钟,和正拨40分钟,效果是相同的。
-20,就对应了 +40。
怎么算的?用 60 减去 -20 的绝对值,即可。
----
另外,100 以内的数字,减去1,和加上 99,效果也是相同的。
比如,27 - 1 = 26, 27 + 99 = (1) 26。
即 -1,就对应了 +99。
怎么算的?用 100 减去 -1 的绝对值,即可。
----
这些,就体现了《模》与《补数》的概念。
利用补数,就可把减法,转换成加法。如果是正数,直接做加法就行,不用费事。
----
对于负数,要用《模》减去这个负数的绝对值,求出《补数》之后再用于计算。
对于正数,就不用变了。
----
八位二进制数字的《模》是 1 0000 0000,即 256。
-5 的补数就是:256 - 5 = 251。
----
把 5、251,都写成二进制数,这就称为了《码》,此时就可以看出它们有《求反加一》的关系。
即把 5 = 0000 0101,求反加一,就有:1111 1011,这就是 -5 的补码,这也就是 251。
----
八位时,补码定义式如下:
[X]补 = X ;0 =< X =< 127
[X]补 = 256 - | X | ;128 =< X < 0
严谨一些的书上都有这个式子。
----
补码完全可以用十进制数表示,编程时,就写十进制数,保证都是正确的。
补码,不必变成二进制,也就不用《求反加一》了,书上讲的那些步骤,都是垃圾。
// 附上代码验证
1 public void demo10(){ 2 byte b1 = (byte)-2; 3 byte b2 = (byte)254; 4 // 证明了 -2 的补码,就是正数254 5 // 254 = 256(byte的模)-2(-2的绝对值) 6 System.out.println(Integer.toBinaryString(b1)); 7 System.out.println(Integer.toBinaryString(b2)); 8 System.out.println(b1 == b2); 9 //11111111111111111111111111111110 10 //11111111111111111111111111111110 11 // true 12 13 int i1 = -199; 14 int i2 = (Integer.MAX_VALUE+1)*2 - 199; // 其中 int 4 个 byte的模为(Integer.MAX_VALUE+1)*2 即2的32次方 15 System.out.println(Integer.toBinaryString(i1)); 16 System.out.println(Integer.toBinaryString(i2)); 17 System.out.println(i1 == i2); 18 //11111111111111111111111100111001 19 //11111111111111111111111100111001 20 //true 21 }