首页 > 代码库 > 谈谈补码与移位
谈谈补码与移位
在计算机中整数的表示使用补码来表示的。
什么是补码呢?首先要明白什么是原码。
数字是有符号的,计算机中,用最高位作为符号位。以四位机器码举例:1的原码表示是:0001; -1 的原码表示是:1001。
也就是说表示实际数值的只有3位。因此4位机器码原码表示数的范围是:[-7, 7],其中0有两种表示,+0: 0000; -0: 1000。
原码表示清晰易懂,但对机器来说却是个麻烦,因为我们必须设计两套电路分别表示加法和减法。
为了统一加减法电路,人们想到了同余原理,让符号位也参与运算,补码应运而生。(反码没有实际应用,没必要记,这里就不解释了,实际上如果不是为了引出正数的补码表示,原码也没必要记)
对于正数,补码表示就是其原码,还以四位机器码举例:1的补码表示是:0001。
对于负数,补码表示就是对于相应的正数表示,连同符号位一起,各位取反后加1。 -1的补码表示为: 1111。(0001 各位取反,1110, 再加1)
对于补码来说,我们没办法直接看出负数的值,想知道负数的真值,我们需要对负数求补,再加上符号位即可。
以-3举例:1101。最高位是1,我们知道它是个负数。对其求补:0010 + 1 = 0011。我们也就知道了其值为-3。
也就是说,正数求补就是其对应的负数,负数求补就是其对应的正数。
对于减法,加上其负数的补码即可。我们成功的把减法运算变成为了加法运算。(不理解同余原理的,可能难以理解。记住结论即可,我不详细展开介绍了)
对于4位机器码来说,补码表示范围为:[-8, 7]。这里0只有一种表示:0000. 所以比原码多表示了一个负数:-8 : 1000。+8的补码为 01000,由于溢出的原因,无法表示。
下面给出8位机器码表示的几个数字的补码:
0 0000 0000
1 0000 0001
2 0000 0010
... ...
127 0111 1111
-1 1111 1111
-2 1111 1110
... ...
-128 1000 0000
有了补码之后,计算机中的加减乘除都可以用加法和求补电路实现,大大简化了电路设计。
下面谈谈移位。这里不多谈,就只谈谈java中的移位操作。
java这种语言竟然有移位操作,确实出乎人意料。不过考虑到java设计初衷是用于嵌入电视机机顶盒的,有这种面向底层的操作倒也不奇怪。
谈到移位,不得不提位运算符 | 或; & 与; ^ 异或; ~ 取反。
这四种都是按位执行,也很简单,不详细展开。记住异或,异1同0即可。
java中左移 << : 高位舍去,低位补0。相当于乘2,当然前提是不溢出。
java中右移 >>: 正数补0,负数补1,低位舍去。相当于除2,易知正数右移,最小得0;负数右移,最小得-1。
上面两种移位操作,称为算术移位,因为它们保存了算术符号,这与C C++是一样的。(左移在不溢出的情况下,符号是不会变化的。不过要注意溢出的发生。)
java中还有一种逻辑右移:>>> , 无论正负,高位补0,低位舍去。这是C C++ 没有的。
谈谈补码与移位