码个蛋(codeegg)第 592 次推文
博客:;utm_medium=website
什么是二进制
二进制是一套计数方法,每个位置上的数有 2 种可能(0 - 1);二进制是计算机的执行语言,但是早在计算机出现前就存在这套计数方法,最早可追溯到古埃及。在日常生活中,我们使用的是十进制,每个位置上的数有 10 种可能(0 - 9),在了解二进制前,先看下十进制是如何运作的。
如十进制下的 101;这里有两个 1 ,代表不同的含义,左边的代表 100 ,右边的代表 1 ,因为左边的 1 在百位,而右边的 1 在个位,同理,中间的 0 在十位。所以十进制的 101 是 “ 百位为 1 ,十位为 0 ,个位为 1 ”,这里的位数对应的是 10 的幂:
二进制的位数对应的是 2 的幂:
所以二进制下的 101 代表 5。下图是二进制的前十位:
二进制转换
计算机运行的是二进制,但是我们在键盘上输入的并非二进制的内容,而是字母、数字(十进制)、汉字等,那计算机是怎么知道把这些内容转成二进制呢?计算机是人设计的,在了解计算机将我们输入的内容转成二进制前,先简单看下十进制和二进制的转换。这里的套路是:
算出 2 的 n 次幂不大于要表示的值;
用要表示的值减去 2的 n 次方,得到剩下的值后,重复步骤 1,直到最后剩下 0 为止。
举个例子,十进制的 107 如何转成二进制,先找出 2 的 n 次幂不大于 107 ,算得 n = 6,用 107 减去 2的6次方 得到 43;重复下来后 :
如果该位用到,用 1 表示,否则用 0 表示。所以 107 用二进制表示为:01101011
二进制转成十进制就是相反的过程,如 01011001 转成十进制:
什么是比特
二进制的表达方式,计算机拥有数十亿超小型的数字电路,这些电路由开关组成,并且开关的状态只有开或关,分别代表二进制中的 1 和 0 。回想那些年我们逃过的数字电路课,依稀记得当时通过调节其中部分电路开关,决定是否让电流通过,可以看到对应开关上的红灯是否被点亮。
计算机中最小的存储单位是二进制位(binary digit),也叫比特, bit 只能够存储 0 或 1 ;而要存储额外的信息(如更大的十进制数),计算机通过串联这些 bit 来完成。这正是它牛逼的地方,只要开关足够多,它可以通过这些 0 和 1 代表任何内容。由 8 bit 串联组成的称为字节(byte),1 个字节可以代表 256 种不同的可能(2的8次方),2 个字节可以代表 65,536 种不同的可能(2的16次方),而这只需要 16 个开关 …
内存是怎么工作的
同时,有一个用于执行内存操作的处理器和内存控制器,内存控制器负责接收处理器的指令,对内存执行读写操作,它可以直接操作内存这个大书架的的每一层,如下:
这里的直接操作有多屌?它意味着我们可以先访问 0 号地址的数据,然后直接访问 12345 号的数据,而不需要在 RAM 这个大书架中挨个寻址到 12345 号。这也是random access memory (RAM)这个名字的由来 — “ 立即访问内存的中随机地址”
虽然内存控制器能够在相隔很远的内存地址间快速切换,但是它还是倾向于访问相邻的地址的内存,计算机在这方面做了优化。处理器有一个缓存用来保存最近从 RAM 中访问的数据的副本,如下:
假如处理器想按顺序,先后访问地址 951、952、953、954 … 在第一次读取地址 951 时就会把所需的内容全部取出来放到处理器的缓存中,之后 952 、953、954 的读取则是通过快速的缓存读取方式获得。
但是假如处理器先后访问的地址是 951、321、146 … 那此时的缓存就帮不上忙了,内存管理器每次都得老老实实的去 RAM 区获取数据,当然速度就会比上面的慢了。
二进制表示数字
上面我们已经知道如何用二进制表示十进制,日常生活中使用的数字范围在在计算机中可以用 4 或 8 个字节(32 或 64 bit)来表示:
比如第2位就是2的(2-1次)方,就是2;第8位就是2的(8-1)次方是128。把所有的值加起来。2(1-1)代表2的0次方,就是1;其他类推 比如二进制1101,换算成十进制就是:1*2(1-1)+0*2(2-1)+1*
二进制还可以用来表示分数、小数、负数:
为了区别不同数制表示的数,通常用右括另外下标数字或字母表示数制,十进制数用D表示,二进制用B表示,十六进制数用H表示,八进制用O表示。例如:101B 表示二进制数。
分数:分别储存两个数:分子和分母
小数:分别存储两个数:去掉小数点后的数字;小数点出现的位置
负数:二进制位中最左边的那一位代表符号,0 表示正数,1 表示负数;
先将52转换成二进制数:00110100B 取反:11001011B 加1:11001100B 则-52D的8位二进制补码为11001100B 如果已知11001100B是有符号数,因为最高位是1,则这个码是用补码表示的一个负数 11001100B减1=11001011B 取反=。
二进制表示字符
了解了计算机如何用二进制表达数字(十进制),那么计算机如何用二进制表达字符呢?计算机用到了编码(encoding)。编码就是一套数字和字符间的映射关系,有许多不同的编码格式,举个常用的例子: ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)。ASCII 编码表可以翻译数字、大小写字母、以及常用的一些特殊符号,有了这套规则,计算机就知道如何应对我们输入的内容了:
假设我们输入的内容为 NICE ,通过 ASCII 编码表首先转化成十进制为:
再转成二进制:
二进制数据是用0和1两个数码来表示的数。【例1103】求1011(2)+11(2) 的和,1011+11,1011+11[1]。拈加法二进制加减乘除外的一种特殊算法。计算机中的十进制小数用二进制通常是用乘二取整法来获得的。
观察上面这个例子发现
一个字符需要 8 bit 来表示,也就是 1 byte
二进制表示字母都以 0 开头
看起来只需要 7 bit 就能表达一个字符,第一个 bit 总是 0 ,给人的感觉好像是浪费了 1 bit,那么当初设计这个表的时候难道没发现这个 bug 么?再看一眼上面的 ASCII 表,我们发现表中缺了很多其他特殊符号,如 é、æ 等等,这些符号计算机要怎么用二进制表达呢?最初设计的 ASCII 编码表只用到了 7 bit ,因此有 128 种可能,再把第一位利用起来,ASCII 编码表就得以翻倍扩展。
还有其他方式可以对字符编码,例如 Unicode 编码表,可以用来表达世界上各个国家的字符,区别在于每个字符占用 2 个 byte(这样理论上一共最多可以表示 2的16次方(即 65536 )个字符。基本满足各种语言的使用。实际上当前版本的 Unicode 码并未完全使用这 16 位编码,而是保留了大量空间以作为特殊使用或将来扩展)。这些编码的核心思想是一致的:建立一套规则作为抽象层,用来简化我们在字符和二进制之间的转化方式。
二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”。二进制数(binaries)是逢2进位的进位制,0、1是基本算符;计算机运算。
近期文章:
Python之父再度为996发声,而我们呢?
Flutter 入门指北之常用布局
程序员写墓志铭……
今日问题:
你还记得二进制吗?
在码个蛋(codeegg)后台回复「社群」即可加入学习群
二进制是只用0和1来表示的,在一串二进制数中,从数的最右边一位开始,向左依次为2的零次方、一次方、二次方,以此推算下去,逢二进一。十进制的2即1*2^1+0*2^0,所以是10(B),如果是十进制的3,则是1*2^1+1*2^0,即
你在看吗?