人类的计数方式通常是“逢十进一”,称为十进制(Decimal),大概因为人有十个手指,所以十进制是最自然的计数方式,各民族的文字中都有十个数字,而阿拉伯数字0-9是目前最广泛采用的。
计算机是采用数字电路搭成的,数字电路中只有1和0两种状态,或者可以说计算机只有两个手指,所以对计算机来说二进制是最自然的计数方式。应用“逢二进一”的原则,十进制的1、2、3、4分别对应二进制的1、10、11、100。二进制的一位数字称为一个位(Bit),三个bit能够表示的最大的二进制数是111,也就是十进制的7。不管用哪种计数方式,数的大小并没有变,十进制的1+1等于2,二进制的1+1等于10,但二进制的10和十进制的2大小是相等的。计算机采用逻辑电路计算两个bit的加法.
电压值进入门电路的输入端,经过逻辑运算后在门电路的输出端输出运算结果的电压值,任何复杂的加减乘除运算都可以分解成简单的逻辑运算。AND、OR和NOT三种逻辑运算分别用与门、或门和反相器实现。另外几种逻辑运算在这里补充一下。下面是异或运算的真值表:
A | B | A XOR B |
0 | 0 | 0 |
0 | 0 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
一句话概括就是:两个操作数相同则结果为0,两个操作数不同则结果为1。
与非(NAND)和或非(NOR)运算就是在与、或运算的基础上取反。下面是NAND的真值表:
A | B | A NAND B |
0 | 0 | 1 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
NOR的真值表:
A | B | A NAND B |
0 | 0 | 1 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 0 |
如果把与门、或门和反相器组合来实现NAND和NOR运算,则电路过于复杂了,因此逻辑电路中通常有专用的与非门和或非门。
加法器是为了实现加法的一种装置。加数和被加数为输入,和数与进位为输出的装置为半加器。若加数、被加数与低位的进位数为输入,而和数与进位为输出则为全加器。常用作计算机算术逻辑部件,执行逻辑操作、移位与指令调用。
对于1位的二进制加法,相关的有五个的量:1,被加数A,2,被加数B,3,前一位的进位CIN,4,此位二数相加的和S,5,此位二数相加产生的进位COUT。前三个量为输入量,后两个量为输出量,五个量均为1位。下面是一位加法器的真值表:
A | B | Cin | Cout | S |
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 0 | 1 |
0 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 0 | 1 |
1 | 0 | 1 | 1 | 0 |
1 | 1 | 0 | 1 | 0 |
1 | 1 | 1 | 1 | 1 |
对于32位的二进制加法,相关的也有五个量:1,被加数A(32位),2,被加数B(32位),3,前一位的进位CIN(1位),4,此位二数相加的和S(32位),5,此位二数相加产生的进位COUT(1位)。
要实现32位的二进制加法,一种自然的想法就是将1位的二进制加法重复32次(即逐位进位加法器)。这样做无疑是可行且易行的,但由于每一位的CIN都是由前一位的COUT提供的,所以第2位必须在第1位计算出结果后,才能开始计算;第3位必须在第2位计算出结果后,才能开始计算,等等。而最后的第32位必须在前31位全部计算出结果后,才能开始计算。这样的方法,使得实现32位的二进制加法所需的时间是实现1位的二进制加法的时间的32倍。
我们已经知道计算机中,所有数据最终都是使用二进制数表达。那么在计算机中,一个负数如何用二进制表达呢。
比如,假设有一 int 类型的数,值为5,那么,我们知道它在计算机中表示为:5
00000000 | 00000000 | 00000000 | 00000101 |
转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。
现在想知道,-5在计算机中如何表示?
在计算机中,负数以其正值的补码形式表达。
什么叫补码呢?这得从原码,反码说起。
原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。
比如
00000000 | 00000000 | 00000000 | 00000101 |
是 5的原码。
反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。
取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)
比如:
00000000 | 00000000 | 00000000 | 00000101 |
每一位取反,得11111111 11111111 11111111 11111010。
称:11111111 11111111 11111111 11111010 是
00000000 | 00000000 | 00000000 | 00000101 |
的反码。
反码是相互的,所以也可称:
11111111 | 11111111 | 11111111 | 11111010 |
和
00000000 | 00000000 | 00000000 | 00000101 |
互为反码。
补码:反码加1称为补码。
也就是说,要得到一个数的补码,先得到反码,然后将反码加上1,所得数称为补码。
比如:
00000000 | 00000000 | 00000000 | 00000101 |
的反码是:
11111111 | 11111111 | 11111111 | 11111010 |
那么,补码为:
11111111 11111111 11111111 11111010 + 1 = 1111111111111111 11111111 11111011
所以,-5 在计算机中表达为:1111111111111111 11111111 11111011。转换为十六进制:0xFFFFFFFB。
再举一例,我们来看整数-1在计算机中如何表示。
假设这也是一个int类型,那么:
1、先取1的原码:
00000000 | 00000000 | 00000000 | 00000001 |
2、得反码:
11111111 | 11111111 | 11111111 | 11111110 |
3、得补码:
11111111 | 11111111 | 11111111 | 11111111 |
可见,-1在计算机里用二进制表达就是全1。16进制为:0xFFFFFFFF。利用调试器,我们可以看到每个变量的16进制值。