一、莱布尼兹发明二进制
1679年3月25日,莱布尼兹写了题为“二进位算术的解释”的论文。在文中,莱布尼兹给出了二进制的计数方法,系统地讨论了二进制和十进制相互转化的法则 ;并给出了二进制的加法与乘除法法则。但莱布尼兹要求不要马上发表他的论文。在论文中他把二进制学术地位定位成“发明”。
1701年11月14日,法国传教士白晋(F. J. Bouvet)在北京给莱布尼兹写了信,这封信辗转法国和英国,1703年4月1日才到达莱布尼兹手中,信中包含伏羲 64 卦方圆图。可以认为,《易经》对二进制的发现起到了激励和印证的作用。实际上,八卦图的数据结构和现代计算机推理系统类似。可以认为周易系统是大 N 系统,所谓万物的数目,就是 2N,当然不可穷尽。与今天的计算机对比,八卦图就是 3 位计算机系统,字长为 8(23),64卦图是 6 位系统,字长为 64(26)。今天的计算机是 64 位系统,字长为 264,可以认为今天的计算机完成的科学计算、媒体介质的数字化处理、管理、数据库、网络通信、模型模拟、机器智能等是基于一个 264 卦系统,每一个卦就是一个由 0 和1 组成的序列,序列的每一位代表有或者没有的意思。
二、二进制的特点
关于这个神奇美妙的数字系统,莱布尼茨只有几页异常精炼的描述。用现代人熟悉的话,我们可以对二进制作如下的解释:
2^0 = 1
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 16
2^5 = 32
2^6 = 64
2^7 = 128
以此类推。
把等号右边的数字相加,就可以获得任意一个自然数。
三、二进制引入到计算机中
(1)技术实现简单,计算机是由逻辑电路组成,逻辑电路通常只有两个状态,开关的接通与断开,这两种状态正好可以用“1”和“0”表示。
(2)简化运算规则:两个二进制数和、积运算组合各有三种,运算规则简单,有利于简化计算机内部结构,提高运算速度。
(3)适合逻辑运算:逻辑代数是逻辑运算的理论依据,二进制只有两个数码,正好与逻辑代数中的“真”和“假”相吻合。
(4)易于进行转换,二进制与十进制数易于互相转换。
(5)用二进制表示数据具有抗干扰能力强,可靠性高等优点。因为每位数据只有高低两个状态,当受到一定程度的干扰时,仍能可靠地分辨出它是高还是低。
四、内存中数据的存储
计算机要处理的信息是多种多样的,如十进制数、文字、符号、图形、音频、视频等,这些信息在人们的眼里是不同的。但对于计算机来说,它们在内存中都是一样的,都是以二进制的形式来表示。
要想学习编程,就必须了解二进制,它是计算机处理数据的基础。
内存条是一个非常精密的部件,包含了上亿个电子元器件,它们很小,达到了纳米级别。这些元器件,实际上就是电路;电路的电压会变化,要么是 0V,要么是 5V,只有这两种电压。5V 是通电,用1来表示,0V 是断电,用0来表示。所以,一个元器件有2种状态,0 或者 1。
我们通过电路来控制这些元器件的通断电,会得到很多0、1的组合。例如,8个元器件有 28=256 种不同的组合,16个元器件有 216=65536 种不同的组合。虽然一个元器件只能表示2个数值,但是多个结合起来就可以表示很多数值了。
我们可以给每一种组合赋予特定的含义,例如,可以分别用 1101000、00011100、11111111、00000000、01010101、10101010 来表示 C、语、言、中、文、网 这几个字,那么结合起来 1101000 00011100 11111111 00000000 01010101 10101010 就表示”C语言中文网“。
一般情况下我们不一个一个的使用元器件,而是将8个元器件看做一个单位,即使表示很小的数,例如 1,也需要8个,也就是 00000001。
1个元器件称为1比特(Bit)或1位,8个元器件称为1字节(Byte),那么16个元器件就是2Byte,32个就是4Byte,以此类推:
8×1024个元器件就是1024Byte,简写为1KB;
8×1024×1024个元器件就是1024KB,简写为1MB;
8×1024×1024×1024个元器件就是1024MB,简写为1GB。
现在,你知道1GB的内存有多少个元器件了吧。我们通常所说的文件大小是多少KB、多少MB,就是这个意思。
单位换算:
8 Bit = 1Byte
1024Byte = 1KB
1024KB = 1MB
1024MB = 1GB
1024GB = 1TB
在内存中没有abc这样的字符,也没有gif、jpg这样的图片,只有0和1两个数字,计算机也只认识0和1。所以,计算机使用二进制,而不是我们熟悉的十进制,写入内存中的数据,都会被转换成0和1的组合。
四、二进制运算法则
五、运算符的使用场景:
用最高效的方法判断一个数是奇数还是偶数?
1 /** 2 * 判断一个数的奇偶性.返回true,为奇数;返回false,为偶数 3 * 4 * @param num 5 * @return 6 */ 7 boolean isOdd(int num) { 8 return (num & 1) == 1; 9 }
1 /** 2 * 交换两个数不使用第三个变量 3 * 4 * 低效的方法: n1 += n2; 5 * n2 = n1 - n2; 6 * n1 = n1 - n2; 7 * 8 * @param n1 9 * @param n2 10 */ 11 void swap(int n1, int n2) { 12 System.out.println("交换前:n1 = " + n1 + ", \t n2 = " + n2); //交换前:n1 = 89, n2 = 20 13 n1 = n1 ^ n2; 14 System.out.println(n1 + "\t" + n2); //77 20 15 n2 = n1 ^ n2; 16 System.out.println(n1 + "\t" + n2); //77 89 两次异或等于没变 17 n1 = n1 ^ n2; 18 System.out.println("交换后:n1 = " + n1 + ", \t n2 = " + n2); 19 } 20 21 public static void main(String[] args) { 22 BitTest bt = new BitTest(); 23 bt.swap(89, 20); 24 }