Java 求补码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ocp114/article/details/82768720
	// 1、简单点
	System.out.println(Integer.toBinaryString(-2));

	// 2、自己写
	/**
	 * 首先,Java 中所有数据都是以补码的形式表示
	 * 反码是什么这里就不说明了
	 * 正数的 补码 = 原码 = 反码
	 * 负数的补码 = 反码 + 1 (注意:符号为始终为1,在原码转反码的时候符号位不变,始终为 1)
	 * @param value 需要取补码是值
	 */
	public static void getComplement(int value) {
		for (int i = 0; i < 32; i++) {
			int t = (value & 0x80000000 >>> i) >>> (31 - i);
			System.out.print(t);
		}
	}

说明:

1、这里要循环 32 次的原因是 int 是 32bit 的数据,如果是 long 的话就是 64 了

2、0x80000000 是 -2147483648 的十六进制表示,是 int 的最小值,二进制表示为 10000000000000000000000000000000,用这个数的原因是首位为 1 ,其余为 0,方便做位运算

3、上面的执行步骤 0x80000000 >>> i 表示 0x80000000 无符号右移 i 位
例如:
i = 2 时
10000000000000000000000000000000 >>> 2 = 00100000000000000000000000000000

4、再用第 3 点的结果和 value 做逻辑与运算,求出 value 的第 i 位是 0 还是 1,起标记作用
例如:
i = 2 , value = 2 时
00100000000000000000000000000000 & 00000000000000000000000000000010 = 00000000000000000000000000000000

5、后面的 >>> (31 - i) 表示把第 4 点求出的值右移 31 - i 位,由于前面的 0x80000000 >>> i 已经移动了 i 位,所以这里再移动 31 - i 位,剩下的值只有 0 或 1 了,也就是上面第 4 点求得的 0 或 1
例如:
i = 2
value & 0x80000000 >>> i = 00100000000000000000000000000000
那么
00100000000000000000000000000000 >>> (31 - i) = 00000000000000000000000000000001

6、最后关键点来了,哈哈哈哈哈!!!
奥秘就在这里
System.out.print(t);
不换行地打印,原来的 i 是从高位到低位循环出来的,这里这样打印就会使得高位先打印,低位排在后面,最后结果也就没错了

7、那么问题来了,为什么要用补码?
     1) 更好地表示 0;
          表示正数 0 时 00000000000000000000000000000000
          表示负数 0 时 10000000000000000000000000000000
          但是无论正数还是负数,0 的补码都是 00000000000000000000000000000000
 
     2) 更好地参与运算
          例如:用补码运算,直接把两个数的补码相加就行(因为 cpu 是没有减法运算的,只有累加器做加法运算)
           -6 + 5 =
            11111111111111111111111111111010
          +
            00000000000000000000000000000101
          =
            11111111111111111111111111111111
          = -1

猜你喜欢

转载自blog.csdn.net/ocp114/article/details/82768720