“道生一,一生二,二生三,三生万物“--《道德经》
1.走进0与1的世界
本质上说,计算机就是晶体管、电路板组装起来的电子设备,无论是图形图像的旋绕、网络远程共享,还是大数据计算,归根结底都是0与1的信号处理。
信息存储和逻辑计算的元数据,只能是0与1,但是它们在不同介质里的物理表现方式却是不一样的,如三极管的断电与通电、CPU的低电平与高电平、磁盘的电荷左右方向。
明确了物理表现方式后,确定他的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”,所以称为二进制。如何在生活中表现二进制,
1=1,10=2,100=4....(每一位逢二进一)
假设有8条电路,那排列组合有2的8次方种情况。代表256种不同的数字信号。
假设区间为0~255,那最大值为-1即255,那么32条电路的话,最大值为4,294,967,295。平时我们说的32位机器,指的就是同时可以处理字长32的电路信号。
如何表示负数?上面8条电路,最左侧电路表示正负,0表示正数,1表示负数。比如01111111代表127,11111111代表-128,取值范围为-128~127。正数的补码与原码,反码一样,而负数的补码是反码加1的结果。比如35 + (-35)如图1-1(a)所示,35-37如图1-1(b)所示。
加减法是高频运算,使用同一个运算器,可以减少中间变量存储的开销,这样也降低CPU内部设计的复杂度,使内部结构更加精简,计算更加高效,无论对于指令、寄存器,运算器都减轻不少负担。
如图1-1(c)所示,计算结果需要9条电路来表示,用8条电路来表达这个计算结果即溢出,即在数值运算过程中,超出规定的表示范围。一旦溢出,结果就是错误的。在各种编程语言中,均规定了不同数字类型的表示范围,有相应的最大值和最小值。
以上示例中的一条电路线在计算机中被称为1位,即1个bit,简写为b。8个bit组成一个单位,称为一个字节,即1个Byte,简写为B。1024个Byte,简写为KB;1024个KB,简写为MB;1024个MB,简写为GB,这些都是计算机中常用存储计量单位。
除二进制的加减法外,还有一种大家既陌生又熟悉的操作:位移运算。陌生是指不易理解且不常用,熟悉是指“别人家的开发工程师”在代码中经常使用这种方式进行高低位的截取、哈希计算,甚至运用在乘除法运算中。向右移一位,近似表示除以2(如表1-1所示),十进制的奇数转化为二进制数后,在向右移时,最右边的1将被直接抹去,说明向右移对于奇数并非完全相当于除以2。在左移<<与右移>>两种运算中,符号位均参与移动,除负数往右移动,高位补1之外,其他情况均在空位处补0,红色是原有数据的符号位,绿色仅是标记,便于识别移动方向。
左移运算由于符号位参与向左移动,在移动后的结果中,最左位可能是1或者0,即正数向左移动的结果可能是正,也可能是负;负数向左移动的结果同样可能是正,也可能是负。
对于三个大于号的>>>无符号向右移动(注意不存在<<<无符号计算方式),当向右移动时,正负数高位均补0,正数不断向右移动的最小值是0,。
在实际运算中,整数为32位,无符号移动mod 32时,为本身,即 35>>1与35>>33是相等的。如果是64位时,无符号移动mod 64为本身,即35>>1与35>>65是相等的。
位逻辑运算,110&101=100 ,110|101=111,~110=001,110^101=100,true&false也是合法的,因为boolean底层就是0和1。