字符集历史和乱码问题(一)

2016-12-22  本文已影响312人  波段顶底

网站乱码问题我们会经常碰到,大多见于非英文的中文字符或其他字符乱码,而且,这类问题常常是因为编码方式问题,主要原因就是所保存的编码方式和浏览器解析时用的编码方式不一致导致。解决办法就是要知道自己是用什么编码方式保存的,并告诉浏览器用你指定的编码方式去解析(在html<head>
里添加<meta charset="编码方式">),否则,浏览器就会用默认的编码方式解析,如果两者不一致则会乱码。

以上一段话,实际已经可以解决标题的问题了。但字符编码(常见有:ASCII、GB2312、GBK、ISOLatin-1、Unicode、UTF-8)是计算机存储技术的基础知识,我觉得还是有必要了解更多一些,比如:为什么计算机非要是二进制而不是其他进制呢?二进制是怎么产生的?计算机是怎么通过二进制存储和读取的?我们电脑上的内存和硬盘有何种区别?32位和64位操作系统指的又是什么?CPU的各种性能指标和二进制的关系?编程又和这些有何关系?等等问题,于是在开启了搜索模式后,便有了下面这个很长很长的故事:

字符编码涉及历史久远,专业术语多,又是计算机的基础,为了让自己对“字符编码”又更加深入的认识,以下内容参考和阅读了大量的文章资料,为了让大家读上去更有趣,有些内容在自己消化后稍有修改,文章太多,无法一一联系授权,侵删。(大概来自于百科、文库、知乎、博客园、CSDN、维基百科、谷歌、饥人谷讲师若愚直播课、阮一峰博客等),文内难免有理解错误之处,请多指正。

关于进位制的发现

我们都知道现在人类是离不开数学运算的,我们古人呢?他们也需要计数啊,比如我打的猎物要怎么样分配给我的爱妃们?我们现在自然很容易理解进位制的(十进制、二进制、七进制、八进制、十二进制、十六进制,二十进制、六十进制)运算,但那个时候我们的古人可不懂啊,人类在很久很久以前,对于10以上的数字是没有概念的。大家都是就着自己的手指头数数,数到10就达到了极限。后来有个基因突变的天才发明了一种做法(可能他发现了复杂的数字都是由简单的数字多次相加得来的道理),让人类的数数能力获得了质的飞升。他是这么做的:数完了自己的手指头,就在自己的身前放一颗小石子(人类的逻辑思维是需要不断进化的,当时可能还记不住)。然后让自己的手指头“清零”,继续数数。数完所有东西后,再回来数数小石子。于是,人类发明了二位数。二位数发明之后,三位数发明也不远了,后来不仅出现了十进制(手指),还出现了二十进制(手指+脚指),再后来发现了二进制、七进制、八进制、十六进制、甚至还有六十进制。十进制是我们现在最能理解和接受的,我们看到100立刻能明白它的意思,但如果看到二进制1100100肯定是懵逼的。所以,二进制虽然最简单,只需要两个基本数值0和1,但使用使用起来却很麻烦,假如你打猎收获3个猎物,就得进位,而进位的计算本来就麻烦,故而,玛雅人宁可使用二十进制数完手指再数脚指也不愿进位。再后来,古人有了月份和地支的概念后,十二进制得以使用(还有个说法是人类除大拇指外的其余四根手指都可弯曲为三节,三四得十二)。再再后来,有了十六进制,这个主要用在计算重量单位,比如十六两合一斤。二十进制据说是玛雅人在用,与使用十进制的人群如华夏人相比,玛雅人在数二十以内的猎物时不需要进位,数完手指再数脚指就可以了,这可能会产生一种思维惰性;华夏人数到十一个猎物就得进位,迫使向更复杂的进位运算前进,这就使一个种族在数学水平上先进了一步。六十进制主要源于中国十天干与十二地支的组合,也仅用于干支纪年。西方用于分割时间上的小时和分钟。七进制东西方都在使用,西方把七天作为一个周期,周而复始地循环;中国则把一个月分为四个星期,大月30天则有两周是8天,小月29天则有一周是8天,虽与西方固定的七天不同,但中国把日月五星谓之七政,也称“七曜”,算是巧合吧。这么多进制,只有十进制最为流行,可能源于这和我们身体结构相似有关,另外,八进制和十六进制最后在计算机中得到了广泛使用。这些进制里面,只有二进制最为简单,这也是计算机为何采用二进制而非其他进制的原因之一。当然,肯定不只这一个原因了,下面会有讲。

扩展阅读:古人的绳结计数法

古人用绳结计数
古埃及人图形计数法

摩尔斯码的发现

这里还有个重要的时间点需要提一下,就是1837年,也就是美国科学家莫尔斯发明的莫尔斯电码,他尝试用一些代码比如: 点、划、点和划之间的停顿、每个字符间短的停顿(在点和划之间)、每个词之间中等的停顿以及句子之间长的停顿来表示不同的字母、数字和标点符号!

为何要提它呢?它本身和二进制是有区别的,但注意时间点,我认为后面发现二进制并诞生计算机和这个存在关系,而且它除了是一种重要的远距离通讯手段外(二战期间被大量使用),更重要的是有助于我们理解字符集的问题,这个文章后面会解释到。

摩尔斯电码表
摩尔斯电码

摩尔斯电码,实际上就是符号与字母数字的对应。

电报的原理是:“点”对应于短的电脉冲信号,“划”对应于长的电脉冲信号,这些信号传到对方,接收机把短的电脉冲信号翻译成“点”,把长的电脉冲信号转换成“划”,译码员根据这些点划组合就可以译成英文字母,从而完成了通信任务。

这里每一个符号其实就是一个字符
而这所有的字符的集合就叫做字符集
“点”或“划”与字符之间的对应关系即可以理解为字符编码
把字符表示为“点”或“划”并对应为电脉冲信号的过程既是编码
译码员把接收机接收到的脉冲信号转化成点划后译成字符的过程即为解码

扩展阅读:
布莱叶盲文与二进制
电报机的原理

半导体特性的发现

半导体特性的发现和应用使得人类从电力时代步入到了信息时代。这为计算机的产生提供了可能,为何这么说?因为半导体被发现的特性使得它能够实现电流的“开、关”功能(原理在下面),这是个很重要的发现。聪明的人类利用半导体材料发明了二极管,而且这个功能是计算机诞生的基石!

二极管的原理

上面说了,半导体可以实现电流“开、关”功能,其基本原理在于PN结,即由带正电的P型半导体(以空穴为载流子)和以带负电的N型半导体(以电子为载流子)形成的界面结。

带正电P型半导体
带负电N型半导体
扩展资料:半导体中的两种载流子-电子和空穴是如何产生和运动的?

注意:这里的0和1只是逻辑表现方法,物理表示就是高电位和低电位,比如可以这样规定:1就表示高电压,0就表示低电压。不要把0和1理解为阿拉伯数字中的0和1

扩展阅读:
手电筒原理
继电器原理

二进制的发现

对于二进制,目前世界数学界公认的是德国数理哲学大师莱布尼茨。对,就是那个和牛顿独立发现微积分的大神。实际上,我国古人的智慧成果--八卦,就是使用阴阳两种元素来表示天地万物的。于是我搜了一下还真有资料,这里面还有个故事:

莱布尼茨在20多岁的时候就已经接触到了中国的《易经》,后于1697年发明了二进制,但由于没有强有力的证据,也没多少人理解,一直没发表。后来31岁时又接触到了古老《易经》里伏羲画的六十四卦卦符,发现和二进制的数码相对应,这给了他极大的启发和鼓舞,于1705年发表了二进制。《周易》归妹章就是讲二进制的:二进制码的每位数都是2的n次幂六三辞 “归妹以须,反归以娣,归幂以须,反归一递,归幂以须,数码位数依须要而定,够用为限,多了无益。”这句话对今天的航天仍具指导意义。航天器上的空间比同体积的黄金还贵,储存器的位数决定卫星的造价。反归一递--卦符的上爻位是2的0次幂1的位置,因易的行文顺序是由初爻(下爻,2的5次幂位)开始依次向上降幂:5、4、3、2、1、0 的顺序,故说反归一递。《易经》还记载:易有太级,是分两仪,两仪生四象,四象生八卦,八卦化万物。后来,莱布尼兹也曾预言过八卦会引起世界性的变革!(老祖宗牛逼啊)

放个两个链接:
八卦与二进制的关系
周易中的二进制数学

很可惜的是,二进制作为一种进位制的计数方法,谁发明并没有多大差别,因为它和我们的十进制一样并不是什么很高级的思想。上面讲了,古人就在用进制,它只是人们规定的一种进位方法。对于任何一种进制---X进制,就表示某一位置上的数运算时是逢X进一位。十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,每一种数制都使用位置表示法。处于不同位置的数符所代表的值不同,与它所在位的权值有关。
十进制1234.55可表示为:
1234.55=1×103+2×102+3×101+4×100+5×10(-1)+5×10(-2)。
可以看出,各种进位计数制中权的值恰好是基础的某次幂。因此,对任何一种进位计数制表示的数都可以写成按权展开的多项式,也就说明各种进制之间可以相互转化的。比如十进制中11这个数计算公式就是这样的:1×10^1 + 1×10^0 = 11。二进制1011这个数计算公式就是这样的:1011 = 1×2^3 + 0×2^2 + 1×2^1 + 1×2^0 = 8 + 0 + 2 + 1 = 11,不论是二进制1011还是十进制11,都代表同一个数字11。

二进制作为计数方法确实够简单,目前我们不可能找到比二进制数字系统更简单的数字系统了(如果把数字1去掉,就只剩下0一个数字,只有一个数字0的数字系统是什么都做不成的)。虽然二进制作为计数方法并不惊艳,但二进制数字系统架起了算术与电之间的桥梁,我们把二进制跟布尔代数,跟数字电路联系起来后,则成就了计算机二进制理论,而计算机是影响人类的重大发明。

计算机中的二进制

自18世纪莱布尼兹发现二进制(基数为2,只用0和1两个数表示,“逢二进一”,“借一当二”)后,人类开动自己的联想,产生了很多有趣的关联。比如上面我们了解的开关、电线、灯泡、继电器、二极管等物体都可以表示二进制数0和1:
电线可以表示二进制数字。有电流代表数字1;没有,则代表数字0。
开关可以表示二进制数字。开关闭合,代表数字1;开关断开,代表数字0。
灯泡可以表示二进制数字。灯泡亮,代表数字1;没亮,代表数字0。
电报继电器表示二进制数字。继电器闭合,代表数字1;继电器断开,代表数字0。
受到启发后,聪明的人类将二进制就和二极管产生了联系,再后来又脑洞大开,决定用8个可以开合的晶体管(一个开关,用“开”来表示1,“关”来表示0)来组合成不同的状态,以表达更多的信息。后来,他们看到8个开关运行状态正常后,给这8个状态起了个名字叫--“字节”。再后来,他们觉得8个状态的字节还可以组合出更多状态来,表达更多的信息,于是他们又做了一些可以处理这些“字节”的机器,在看到他们也运转正常后,觉得这一定是上帝的旨意。于是,他们给这个机器又起了一个非常牛逼的名字--“计算机”(当时一台计算机足有一间半教室那么大,六头大象的重量)。所以,我们明白了计算机中的二进制实际上就是一个非常微小的开关,用“开”来表示1,“关”来表示0,0和1各占一个“位”,用8个不同状态的0和1表示“字节”,通过“字节”组合不同的状态来存储和运算不同数据。

扩展阅读:
第一代计算机-电子管计算机
第二代计算机-晶体管计算机

计算机中为什么要用二进制而不是其他进制?

计算机使用二进制是由它的实现机理决定的。上面说过,电脑的基层部件是由集成电路组成的,这些集成电路可以看成是一个个门电路组成,(当然事实上没有这么简单的)。当计算机工作的时候,电路通电工作,于是每个输出端就有了电压。电压的高低通过模数转换即转换成了二进制:高电平是由1表示,低电平由0表示。也就是说将模拟电路转换成为数字电路。这里的高电平与低电平可以人为确定,一般地,2.5伏以下即为低电平,3.2伏以上为高电平。电子计算机能以极高速度进行信息处理和加工,包括数据处理和加工,而且有极大的信息存储能力。数据在计算机中以器件的物理状态表示,采用二进制数字系统,计算机处理所有的字符或符号也要用二进制编码来表示。用二进制的优点主要在于:

除了以上优点外,采用二进制还有个客观原因在于,人们知道,具有两种稳定状态的元件(如晶体管的导通和截止,继电器的接通和断开,电脉冲电平的高低等)在那个时代容易找到,而要找到来对应十进制的10个数的具有10种稳定状态的元件在那个时代就非常困难了。这也是计算机为何采用二进制而非人类更熟悉的十进制的原因吧。

为什么又会出现八进制、十六进制?

人类一般思维方式是以十进制来表示的,而计算机则是二进制,但是对于编程人员来说,都是需要直接与计算器打交道的,如果给我们一大串的二进制数。比如说一个4个字节的int型的数据:0000 1010 1111 0101 1000 1111 11111 1111,我想任何程序员看到这样一大串的0、1都会很蛋疼。所以必须要有一种更加简洁灵活的方式来呈现这对数据了。你也许会说,直接用十进制吧,如果是那样,就不能准确表达计算机思维方式了(二进制),所以,出现了八进制、十六进制,其实十六进制应用的更加广泛,就比如说上面的int型的数据,直接转换为八进制的话,32./3 余2 也就是说,我们还要在前面加0,但是转换为十六进制就不同了。32/4=8,直接写成十六进制的8个数值拼接的字符串,简单明了。所以说用十六进制表达二进制字符串无疑是最佳的方式,这就是八进制和十六进制出现的原因。

扩展阅读:各进制之间如何转换

进制间的相互转换问题

计算机中二进制何以表达万物?它是如何读懂二进制码的?

计算机是怎样用二进制0和1来表达信息的,甚至号称可以表达宇宙万物所有信息呢?
我们知道编程语言里的基本数据类型,都是以符合人类世界和自然世界的逻辑而出现的,便于让人更容易理解,可以说,这些数据类型是架通人类思维与计算机的桥梁。
但是我们同时也知道,依照冯诺依曼体系,计算机中并没有这些数据类型,而全部都是0和1表示的二进制数据,并且计算器只能理解这些0和1的数据。既然,所有的数据在计算机里面都是以0和1存储和运算的,那么,符合我们人类思维的数据则都要通过一定的转换才能被正确的存储到计算机中。转化的原理是什么呢?
举个栗子:假如你看上一个学妹,你想表白,所以你送了她一件礼物,如果学妹接受了礼物表示接受你,决绝了礼物表示拒绝你。也就是我们可以用0和1来表达学妹的态度(实际情况可能更复杂)。
再举个栗子:有两个人A和B去看了一个电影,怎么用0和1表示呢?我们用0代表讨厌,1代表喜欢。会出现:
00 = AB都不喜欢这影片
01 = A讨厌它,B喜欢它
10 = B喜欢它,A讨厌它
11 = AB都很喜欢这影片
如果加上我的观点呢,它就变成2^3次方=8种可能了。如:000、001、010、011、100、101、110、111,所以,计算机的二进制虽然无法和人一样理解那么多,但有了这0和1,计算机就可以通过“开”和“关”的状态来做二元逻辑判断(真假、对错、是否等非黑即白的问题)了,不要小看这二元逻辑判断,不客气的说它确实可以表达宇宙万物(道德经:道生一,一生二,二生三,三生万物)!我们不要忘记,发明二进制的莱布尼兹不但是个数学家,还是个牛逼的哲学家啊,他一直试图用数学符号和操作符来表达亚里士多德的逻辑理论,而且他也是最接近这个目标的人,直到后来乔治·布尔在概念上的突破成果--布尔代数的出现。

大部分计算机内部的连接是一样的,都是通过电气信号来进行通信的,也就是电压高低的变化,这些电流会经过 MOSFET 晶体管,晶体管中包含 N 型半导体和 P 型半导体,通过电压就能控制线路开闭,然后这些 MOSFET 构成了 CMOS,接着再由 CMOS 实现「与」「或」「非」等逻辑电路门,最后由逻辑电路门上就能实现加法、位移等计算。

配套逻辑运算:与、或、非。

a---饿了想要吃点儿东西。
b---循坏进食的动作10次。
c---如果吃饱了,到d;否则,到b。
d---结束进食的动作。

如果这还不足以说服你,只能建议你去研究图灵机了。图灵机处理信息远比这个复杂的多。还以上面的举例:

a---饿了想要吃点儿东西。
b---循坏进食的动作10次。(该减肥了?是则挂起,否则继续)
c---如果吃饱了,到d;否则,到b。
d---结束进食的动作。

如果b反复执行到一半的时候,你发现自己是不是该考虑减肥了。如果是,这时候图灵机就会立刻优先对这个新的减肥输入进行处理而会将循环进食的动作挂起,如果不是,则唤醒刚才被挂起的动作,继续进行。也就是说我们每个人都是一个非常非常复杂的图灵机,上面只是一种情况,而人的情况指令要比这个例子复杂的多,这也是为什么人工智能总是达不到真实人的程度,当然,如果这个理论正确,假设我们也是高级文明创造的复杂版的图灵机的话,谁又能保证人工智能不会进化呢?所以,这个宇宙中的一切,都可以抽象成图灵机,二进制可以表达一切!

图灵机简图
电影-图灵

虽然,这个世界上的所有事件,都可以用顺序、选择、循环三种逻辑来表示。虽然二进制可以表达宇宙万物。但是,可以表达一切现象并不代表可以解决一切问题。
例如:显示自己本身的所有代码。
比如有这样一个程序,就一行:

显示(100)

这个程序就做一件事情:显示数字100。
问题来了,你如何把“显示(100)”这两个汉字一组括号和一个数字100显示出来呢?
似乎应该这样:

显示(显示(100))

但是其实当你这样做的时候,你已经改变了程序本身,现在的程序为两个“显示”两组括号和一个100,而你运行程序后只能显示一个“显示”一组括号和一个100,很显然你并没有把这个程序全部显示出来。

类似这样的问题,就是计算机无法解决的问题(好像类似先有蛋还是先有鸡的问题)。

再比如“背包问题-贪心算法”(一种组合优化的NP完全问题):
一个小偷去博物馆偷东西。博物馆内有3件物品。

第一件物品的重量为3, 价值为4;
第二件物品的重量为2, 价值为3;
第三件物品的重量为4, 价值为5;
小偷的背包最多可以承受的重量为7。

请问:应该如何拿物品,可以让背包里的物品总价值最大(不能重复装入)?
这个问题似乎非常简单,稍微比较后就会得出结论:拿第一件和第三件物品。

但是,如果我们扩大一下问题:如果有6件物品、背包可以承受的重量也提高一些,应该怎么拿?这个时候如果让计算机去解决这个问题,我们就会发现当问题的规模扩大1倍后,计算机所需要的时间却扩大了远不止1倍 --- 即解决问题所需时间不再是线性变化了。

就拿这个问题来说,如果物品数量超过十几个,那么计算机要想解决这个问题所需要的时间就已经超过了100年。

这类问题是计算机或者说用那三种逻辑顺序可以解决的、但是所需要的时间是人类无法容忍的。

扩展阅读:
逻辑门电路
逻辑与、或、非
认识图灵机
数学危机与图灵机
图灵机视频
如何自己造一台8位计算机

二进制和编程有什么关系?

计算机读取二进制编码,不是单纯的二进制数,而是严格按照一定的格式来编码的。读指令这些操作都是靠计算机里的CPU来进行的,按照冯诺依曼体系,CPU里有一个控制寄存器(一堆代表0和1的开关)。这样我们可以用一组二进制数来描述这个控制寄存器的状态。开关的多少就是一条指令的长度,我们经常见的32位机,就是一条指令长为32,就是这个控制有32个小开关。同样64位机有64个。在寄存器内,各个位有的是单独工作的,有的是好几个一起工作的,我们把他们分成一个个小组。有的组是表示状态的,只能读不能写,或者说写了也没用。而有的组是可以操作的。而且这些组是可以在一定条件下改变的,用来实现某个功能。对于那些可以操作的寄存器是有特定功能的,比如说有个开关你拨一下,它就伸出个腿什么的,你拨回去它就缩回来。这样我们按照上面的格式写给CPU一串二进制编码,他就能按照我们意愿完成某个动作。这个编码格式其实就跟你喊:电脑,电脑,给我个鸡腿!或者:妈,我饿了!是一样一样的。这些二进制0和1的编码动辄几十位,电脑是好认了,可是让程序员怎么读?既然上面说的格式固定,那就用一些字符来代替寄存器组吧!这样汇编语言就诞生了,当然汇编是按照机器的模式来的,还是不好理解,那C语言等等一些语言就出来了。而我们也有代码写了!程序员干的工作实际上就是,为了让计算机解决某个问题而使用某种程序设计语言编写程序(编译后的代码集合)来和计算机沟通,并最终得到相应结果的过程。程序员写好的程序会按照CPU能认识的格式来生成二进制文件,每条指令的长度固定。这样CPU每次读一点,按照读出的指令来完成相应的动作,然后再读下一条。这样就可以完成程序交给它的任务了。当然不同的CPU的控制寄存器个数不相同,但是大致原理都差不多。也就是说,程序员干的事实际就是在和计算机约会。(程序员没有女朋友难道是这个原因?)

CPU结构

内存是怎么工作的?

举例说明

内存地址

扩展阅读:
内存工作原理

计算机如何存储数据的?

数据类型一般分类基本数据类型和复合数据类型,复合数据类型也是由基本数据类型构成的。所以,这里先只讨论基本数据类型(无符号整形,带符号整形,实型,char型)的存储情况。

  1. 为什么原码不行?
    ( 1 )10- ( 1 )10 = ( 1 )10 + ( -1 )10 =( 0 )10
    (00000001)原+ (10000001)原 = (10000010)原 = ( -2 ) 显然不正确。
    通过上面原码计算式可以看出,当正数加上负数时,结果本应是正值,得到的却是负值(当然也有可能得到的是正数,因为被减数与减数相加数值超过0111 1111,即127,就会进位,从而进位使符号位加1变为0了,这时结果就是正的了)。而且数值部分还是被减数与减数的和。并且,当负数加上负数时(这里就拿两个数值部分加起来不超过0111 1111的来说),我们可以明显看出符号位相加变为0,进位1被溢出。结果就是正数了。因此原码的错误显而易见,是不能用在计算机中的。
  2. 补码的原理
    既然原码并不能表示负数的运算问题,那么当然要另想他法了。这个方法就是补码,不得不说,这是一个最简洁的方法,当然,也可以用别的更复杂的方法,那就不是我们想要的了。我自己研究补码的时候,也在网上找了些资料,都是到处copy,反正我是看的迷糊了,本人数学功底不怎么样,看不懂那些大神写的,只好,自己理解了下。要谈补码,先看看补数的问题。什么是补数,举个简单的例子,100=25+75。100用数学来说就是模M,那么就可以这样概括。在M=100的情况下,25是75的补数。这就是补数。25是75的补数,这是在常规世界中,在计算机上就不是这样了,因为,在计算机中,数据存在溢出的问题。假设机器字长是8的话,那么能表达的最大无符号数就是1111 1111,在加1的话,就变成1 0000 0000 ,此时因为溢出,所以1去掉,就变成0了,
    也就是说,在计算机中,补数的概念稍微不同于数学之中,25+75=100,考虑计算机中的溢出问题,那么25+75就等于0了。也就是说,25和75不是互为补数了。我觉得用闹钟来比喻这个问题再形象不过了,因为闹钟也存在着溢出的问题,当时间到达11:59 ,在加1分钟的话就变成0:0了,这和计算机的溢出是同一个道理。那么,有一个时钟,现在是0点,我想调到5点,有两种方法,一个是正着拨5,到5点。第二种方法是倒着拨7,也可以到5点。正着拨5记作+5,倒着拨7,记作-7,而闹钟的M是12,也就是说,在考虑溢出的情况下,M=12,5是-7的补数。用个数学等式可以这样表0+5=0+-7,即0+5=0-7,这就是计算机中的数值计算和数学中的计算不同的地方。
    明白了计算机中补数的道理,那么就明白补码的问题了。还是用例子说明:
    在计算机中计算十进制 1+(-2)。
    1的原码是:0000 0001
    -2的原码是:1000 0010
    -2的补码是:1111 1110 这个二进制换做无符号的整数大小就是254,而8位二进制数的M=28=256。(很多文章中把M写成27,这根本就是不对的,根本没有解决符号位的问题)你发现什么了没?当换成补码后,-2和254就是补数的关系。也就是1+(-2)等价于了1+254了。这样做,好处在什么地方,你自己都可以看得到:
    1):利用补数和溢出的原理,减法变成了加法。
    2):符号位不在是约束计算的问题,不会存在原码中的问题了,因为变成补码后,虽然最高位依然是1,但是这个1就不在是做为符号位了,而是作为一个普通的二进制位,参与运算了。
    所以,这就是补码的原理所在,通过补数和溢出,解决了减法和负数问题。
  3. 十进制数求补码,补码求十进制数
    十进制求补码:
    如果是正数,直接求它的原码,符号位为0
    如果是负数,比较好的方法是先求十六进制,在由十六进制求二进制,符号位为1,在除了符号位都取反,在加1,即可得到补码。
    补码就十进制 :
    根据符号位判断,如果符号位是0,表示是正数,就是原码,直接转换就十进制即可。
    如果符号为是1,表示是负数。那么,连符号位在内都取反,在加1,将该二进制转换为十进制,该十进制数即使该负数的绝对值,加个负号-,就得到该负数。

点击接着阅读

上一篇 下一篇

猜你喜欢

热点阅读