• 全部
  • C语言程序设计
  • 数据结构
  • 计算机操作系统
  • 计算机网络
  • 计算机组成原理
  • 考研资讯
  • 备考指南

深入计算机组成原理(十一)二进制编码:“手持两把锟斤拷,口中疾呼烫烫烫”?

  • 计算机组成原理
作者:小问号阿

上算法和数据结构课的时候,老师们都会和你说,程序=算法+数据结构。如果对应到组成原理或者说硬件层面,算法就是我们前面讲的各种计算机指令,数据结构就对应我们接下来要讲的二进制数据。

众所周知,现代计算机都是用0和1组成的二进制,来表示所有的信息。前面几讲的程序指令用到的机器码,也是使用二进制表示的;我们存储在内存里面的字符串、整数、浮点数也都是用二进制表示的。万事万物在计算机里都是0和1,所以呢,搞清楚各种数据在二进制层面是怎么表示的,是我们必备的一课。

大部分教科书都会详细地从整数的二进制表示讲起,相信你在各种地方都能看到对应的材料。

我们重点来看一看,大家在实际应用种最常遇到的问题,也就是文本字符串是怎么表示成二进制的,特别是我们会遇到的乱码究竟是怎么回事。我们平常在开发的时候,所说的Unicode和UTF-8之间有什么关系。理解了这些,相信以后遇到任何乱码问题,你都能手到擒来。

理解二进制的“逢二进一”

二进制和我们平时用的十进制,其实并没有什么本质区别,只是平时我们是“逢十进一”,这里变成了“逢二进一”而已。每一位,相当于十进制下的0~9这十个数字,我们只能用0和1这两个数字。

任何一个十进制的整数,都能通过二进制表示出来。把一个二进制数,对应到十进制,非常简单,就是把从右到左的第N位,乘上一个2的N次方,然后加起来,就变成了一个十进制数。当然,既然二进制是一个面向程序员的“语言”,这个从右到左的位置,自然是从0开始的。

比如0011这个二进制数,对应的十进制表示就是

表示十进制的3。

对应地,如果我们想要把一个十进制的数,转换成二进制,使用短除法就可以了。也就是,把十进制数除以2的余数,作为最右边的一位。然后用商继续除以2,把对应的余数紧靠着刚才余数的右侧,这样递归迭代,直到商为0就可以了。

比如,我们想把13这个十进制数,用短除法转化成二进制,需要经历以下几个步骤:

因此,对应的二进制数,就是1101.

刚才我们举的例子都是整数,对于负数来说,情况也是一样的吗?我们可以把一个数最左侧的一位,当成是对应的正负号,比如0为正数,1为负数,这样来进行标记。

这样,一个4位的二进制数,0011就表示为+3.而1001最左侧的第一位为1,所以它就表示-3.这个其实就是整数的原码表示法。原码表示法有一个很直观的缺点就是,0可以用两个不同的编码来表示,1000表示0,0000也表示0.习惯万事一一对应的程序员看到这种情况,必然会被逼死。

于是,我们就有了另一种表示方法。我们仍然通过最左侧的第一位的0和1,来判断这个数的正负,但是,我们不再把这一位当成单独的符号位,在剩下几位计算出的十进制前加上正负号,而是在计算整个二进制值的时候,在左侧最高位前面加个负号。

比如,一个4位的二进制补码数值1011,转换成十进制,就是

值为-5。
如果最高位是1,这个数必然是负数,最高位是0,必然是正数。并且,只有0000表示0,1000在这样的情况下表示-8.一个4位的二进制数,可以表示从-8到7这16个整数,不会白白浪费一位。

当然更重要的一点是,用补码来表示负数,使得我们的整数相加变得很容易,不需要做任何特殊处理,只是把它当成普通的二进制相加,就能够得到正确的结果。

我们简单一点,拿一个4位的整数来算一下,比如-5+1=-4,-5+6=1.我们各自把它们转换成二进制来看一看,如果它们和无符号的二进制整数的加法用的是同样的计算方式。这也就意味着它们是同样的电路。

字符串的表示,从编码到数字

不仅数值可以用二进制表示,字符乃至更多的信息都能用二进制表示。最典型的例子就是字符串(Character String)。最早计算机只需要使用英文字符,加上数字和一些特殊符号,然后用8位的二进制,就能表示我们日常需要的所有字符了,这个就是我们常常说的ASCII码

ASCII码好比一个字典,用8位的二进制种的128个不同的数,映射到128个不同的字符里。比如,小写字母a在ASCII里面,就是第97个,也就是二进制的0110 0001,对应的十六进制就是61,而大写字符A,就是第65个,也就是二进制的0100 0001,对应的十六进制表示就是41.

在ASCII码里面,数字9不再像整数表示法里面一样,用0000 1001来表示,而是用0011 1001来表示。字符串15也不是用0000 1111着8位来表示,而是变成两个字符1和5连续放在一起,也就是0011 0001和0011 0101,需要用两个8位来表示。

我们可以看到,最大的32位整数,就是2147483647.如果用整数表示法,只需要32位就能表示了。但是如果用字符串来表示,一共有10个字符,每个字符用8位的话,需要整整80位。比起整数表示法,要多占很多空间。

这也就是为什么,很多时候我们在存储数据的时候,要采用二进制序列化这样的方式,而不是简单的把数据通过CSV或者JSON,这样的文本格式存储来进行序列化。不管是整数也好,浮点数也好,采用二进制序列化会比存储文本省下不少空间。

ASCII码值表示了128个字符,一开始倒也还好,毕竟计算机是在美国发明的,然而随着越来越多的国家用上了计算机,想要表示譬如中文这样的文字,128个字符显然是不太够用的。于是,计算机工厂是们开始各显神通,给自己国家的语言创建了对应的字符集(Charset)和字符编码(Character Encoding)。

字符集,表示的可以是字符的一个集合。比如“中文”就是一个字符集,不过这样描述一个字符集并不准确。想要更精准一点,我们可以说,“第一版《新华字典》里面出现的所有汉字”,这是一个字符集。这样,我们才能明确直到,一个字符在不在这个集合里面。比如我们日常说的Unicode,其实就是一个字符集,包含了150种语言的14万个不同的字符。

而字符编码则是对于字符集里的这些字符。怎么一一用二进制表示出来的一个字典。我们上面说的Unicode,就可以用UTF-8,UTF-16、乃至UTF-32来进行编码,存储成二进制。所以,有了Unicode,其实我们可以用不止UTF-8一种编码形式,我们也可以自己发明一套GT-32编码,比如就叫做Geek Time 32好了。只要别人知道这套编码规则,就可以正常传输、显示这段代码。

同样的文本,采用不同的编码存储下来。如果另外一个程序,用一种不同的编码方式来进行解码和展示,就会出现乱码。这就好像两个军队用密语通信,如果用错了密码本,那看到的信息就会不知所云。在中文世界里,最典型的是“手持两把锟斤拷,口中疾呼烫烫烫”的典故。

既然今天要彻底搞清楚编码知识,我们就来弄清楚“锟斤拷”和“烫烫烫”的来龙去脉。



首先,“锟斤拷”的来源是这样的。如果我们想要用Unicode编码记录一些文本,特别是一些遗留的老字符集内的文本,但是这些字符在Unicode种可能并不存在。于是,Unicode会统一把这些字符记录为U+FFFD这个编码。如果用UTF-8的格式存储下来,就是\xef\xbf\xbd。如果连续两个这样的字符放在一起,\xef\xbf\xbd\xef\xbf\xbd,这个时候,如果程序把这个字符,用GB2312的方式进行decode,就会变成“锟斤拷”。这就好比我们用GB2312这本密码本,去揭秘别人用UTF-8加密的信息,自然没办法读出有用 的信息。

而“烫烫烫”,则是因为如果你用了Visual Studio的调试器,默认使用MBCS字符集。“烫”在里面是由0xCCCC来表示的,而0xCC又恰好是未初始化的内存的赋值。于是,在读到没有赋值的内存地址或者变量的时候,电脑就开始大叫“烫烫烫”了。

了解了这些原理,相信你未来在遇到中文的编码问题的时候,可以做到“手中有粮,心中不慌”了。

总结延伸

到这里,相信你发现,我们可以用二进制编码的方式,表示任意的信息,只要建立起字符集和字符编码,并且得到大家的认同,我们就可以在计算机里面表示这样的信息了。所以说,如果你有心,要发明一门自己的语言并不是什么难事。

不过,光是明白怎么把数值和字符在逻辑层面用二进制表示是不够的。我们在计算机组成里面,关心的不只是数值和字符的逻辑表示,更要弄明白,在硬件层面,这些数值和我们一直提的晶体管和电路有什么关系。下一讲,我会从时钟和D触发器开始讲起,最终让你明白,计算机里的加法,是如何通过电路来实现的。

思考

你肯定会计算十进制整数的加减法,二进制的加减法也是一样的。如果二进制的加法中,有数是负数的时候该怎么处理呢?我们今天讲了补码的表示形式,如果这个负数是原码表示的,又应该如何处理?如果是补码表示的呢?请你用二进制加法算一下,-5+4=-1,通过原码和补码是如何进行的?

  • 发表于 2020-07-03 10:53
  • 阅读 ( 430 )
  • 分类: 数据的表示和运算

0 条评论

请先 登录 后评论

关于作者

caozhongya
获得点赞 18
文章被阅读 621

你可能感兴趣的文章

相关问题

caozhongya
caozhongya

150 篇文章

作家榜 »

  1. L^*^L 218 文章
  2. 李恒 155 文章
  3. caozhongya 150 文章
  4. 杜肖肖 107 文章
  5. 周洋 94 文章
  6. 躲雨的聪 92 文章
  7. 李恒涛 78 文章
  8. 胡鹏 61 文章

零柒月平度网站建设全国中学排名前十如何设置网页在同一窗口打开倒数第二个男朋友徐州地区天气预报国内寿险公司排名荆门市建设工程造价管理站360免费建站独立域名网页怎么做商城网页加载速度慢怎么办宜昌市建筑装饰装修监督站浙江二建报名网站入口专业关键词排名优化软件智能音响品牌排行榜前十名服务器自建网站dnf9.24版本职业排名怎么创建网站教程比特病毒做神马关键词排名软件贵州省二级建造师报考网站建设开发营销网站作业精灵网页图为先云南会计网官网首页清华大学a类专业排名okooo澳客竞彩网首页电脑版起点中文网网页东莞市建设局网站网页内容禁止复制怎么办中国期货公司排名多地新政:核酸筛查不必全员参与阳性妈妈照顾抑郁症儿子居家获批坚持第九版 落实二十条吃橘子会变阳性?记者亲测喀麦隆首发门将临赛前“跑”了专家称现在的年轻人不容易妥协北京新增本土957+3429 社会面490例比利时国家队内讧上海迪士尼乐园暂时关闭房地产股掀涨停潮广州警方通报男孩地铁里被硫酸灼伤上财校长称博士生像乞丐一样在研究巴德年院士:我与巴颖没有任何关系卡塔尔游客多到骆驼加班胡锡进建议:各地别大规模建方舱了C罗发文庆祝晋级16强多人讲述感染新冠后的故事摄像师身体不适坐地休息3次被辞B费2球2助!葡萄牙真正大腿出炉卫健局回应核子基因核检业务违规C罗上帝之发专家谈核子华曦为何没被公诉河北出现零下30℃极端低温张核子和他的“核酸版图”极寒天气致新疆阿勒泰7名工人遇难俄罗斯杯爆发大规模冲突 6人染红男子介绍未成年有偿陪侍获刑证监会:恢复上市房企再融资女子怀孕近7个月被丈夫施暴兰州气象局回应网友拍到不明发光体

零柒月 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化