为什么8位的二进制补码范围是[-128,127]
原码-反码-补码及运算
原码,反码,补码及运算一、定义1.原码正数的符号位为0,负数的符号位为1,其它位按照一般的方法来表示数的绝对值。
用这样的表示方法得到的就是数的原码。
【例2.13】当机器字长为8位二进制数时:X=+1011011 [X]原码=01011011Y=-1011011 [Y]原码=11011011[+1]原码=00000001 [-1]原码=10000001[+127]原码=01111111 [-127]原码=11111111原码表示的整数范围是:-(2n-1-1)~+(2n-1-1),其中n为机器字长。
则:8位二进制原码表示的整数范围是-127~+12716位二进制原码表示的整数范围是-32767~+327672.反码对于一个带符号的数来说,正数的反码与其原码相同,负数的反码为其原码除符号位以外的各位按位取反。
【例2.14】当机器字长为8位二进制数时:X=+1011011 [X]原码=01011011 [X]反码=01011011Y=-1011011 [Y]原码=11011011 [Y]反码=10100100[+1]反码=00000001 [-1]反码=11111110[+127]反码=01111111 [-127]反码=10000000负数的反码与负数的原码有很大的区别,反码通常用作求补码过程中的中间形式。
反码表示的整数范围与原码相同。
3.补码正数的补码与其原码相同,负数的补码为其反码在最低位加1。
引入补码以后,计算机中的加减运算都可以统一化为补码的加法运算,其符号位也参与运算。
【例2.15】(1)X=+1011011 (2)Y=-1011011(1)根据定义有:[X]原码=01011011 [X]补码=01011011(2)根据定义有:[Y]原码=11011011 [Y]反码=10100100[Y]补码=10100101补码表示的整数范围是-2n-1~+(2n-1-1),其中n为机器字长。
则:8位二进制补码表示的整数范围是-128~+127(-128 表示为10000000,无对应的原码和反码)16位二进制补码表示的整数范围是-32768~+32767当运算结果超出这个范围时,就不能正确表示数了,此时称为溢出。
关于补码、原码、反码的深度思考
关于补码、原码、反码的深度思考关于补码,原码,反码的问题,说简单,很简单,基本人人都会算,会求解。
可是没几个人能对这几个概念的来龙去脉搞得清清楚楚,明明白白的. 比如,为什么引入编码,为什么引入原码,又为什么引入反码. 反码存在的意义是什么,补码的引入原因,为什么补码能够把符号位一起运算?补码的优势到底在哪里?根据韩大师的指示(韩宏博士),我们应该对问题多多思考,多想几个为什么. 如果你搞不懂来龙去脉,恐怕后面的操作几乎可以把你搞得晕头转象,好象懂了,会做题了.可是心理总觉得没吃透,对吧??下面我把我的思考分享给大家:计算机的基本功能是对信息进行处理.所以我们引出了一个重要的概念信息表示的数字化,包括信息的表示 ,信息的存储,信息的转化,信息的加工,信息的传送,和对这些过程的控制.首先,我们把重点放在信息的表示,计算机中进位记数制,我想应该都明白为什么用二进制吧? 然后我们就需要对它进行编码? 为什么要进行编码呢,在人脑中只是约定了+为正数,-为负数,就可以在人脑中进行高度抽象的运算了,但是,在计算机中不行啊,计算机很傻的,计算机中的任何行为都依赖于它的物理结构,它没有思维的. 所以你必须告诉它什么是正,什么是负! 所以我们必须进行编码,以区分正负.原码的出现与衰落最开始的时候,人们约定在数前面第一位用做表示符号的位, 1表示负0 表示正. 他们称之为原码. 很不错,可以成功的区分出正负了. 可是马上就意识到它的一些局限性了.1加减的不方便, 符号位需要单独处理,单独判断.同0相加或相减,那好判断. 可异号呢? 那就涉及一个判断是否够减的逻辑了.很难做到.2 +0 表示为 0000-0 表示为 1000,这就存在二义性了,计算机中是绝对不能容惹二义性的东西存在的.补码的大放光彩原码的缺点使人们要找出一种新的编码,这种编码就是补码.首先它必须继承原码的特点(可以表示正负)而且它至少应该有两个优点,可以把符号位一起运算和0没有二义性.怎么才能做到呢? 如果是你,你能创造出这种编码吗?在日常生活中,我们发现时钟有这样一个特点,就是以12为模,13点是多久呢?舍弃模12 大家都知道就是1点了. -1 点也就是11点. 两者是完全等价的,因为它们有模12. 通过这个特点可以做什么? 大家注意了,可以变减为加啊,比如:-1点再过5个小时是几点, -1+5=4点,我们可以这样变换 (-1+12)+5=4 ,你会发现这个等式是不是错了?应该是16对啊,你错了,满12就已经溢出了,只剩下4.而计算机是否也有这个特点呢?答案是肯定的,实现模运算的基础显然就是寄存器的长度是固定的.那么变减为加那就算是实现了.例如82-54=82+46= (1)28 ,那么到底是怎么样才能把符号位一起运算呢?我们知道正数的补码就是本身,负数的补码就变反加一. 我们来举个例子比如异号想加 A-B=87-25,我们把它转换成补码=0(87)+1(75)=062,嘿嘿,发现没有符号位一起运算了.结果为62,再来,把它反过来 25-87 ,转换成补码0(25)+1(13)=1(38),这里有的同会说,不对了,结果不应该是-38. 你再仔细看看,我提示下补码+补码=? ,也是等于补码啊,1(38)的真值是-62,对吧? 完全可以把符号一起运算.最关键的部分就在这里了,把符号位一起运算的理论依据是什么,什么样的编码可以连同符号位一起运算,而原码为什么不能把符号位一起运算? 经过我一天一夜的思考 :),大家看看这样理解对不对. 数 A ,有正有负,对吧? 也就是A+(-A)=0 ,哈哈,就是它了,我们设A=0001,你看原码,A=00001,-A=10001,A+(-A)=10010,哈哈1+(-1),变成-2了,再看补码00001+11111=00000,哈哈,完全正确,你如果再要去想为什么,也很简单了一个数加去它的补数=什么? 当然=模了,模的定义就是模减去一个数的结果就是这个数的补数. 等于模了,舍去模,那不就变成0 了. 这就是连同符号位一起运算的依据.你还会发现一个特点,这个特点在我们物理上的具体实现时是相当重要的.请看原码 0001=0000000001,而1001是否等于111111111001呢,很明显是不可能的. 而补码1001绝对是等于1111111001的,不信你算算看,这个性质就叫符号的可扩充性.反码的出现原因哈哈,补码很明显是我们的最佳选择了,为什么又弄一个叫反码的东西来,我看到这里的时候也是很不理解,还是韩大师那句话,要多思考.它是怎么回事呢?它的思路应该是反过来的,我们联系联系具体的逻辑元器件,是不是有个非门的东西啊?你是1它变成0,0变成1,说白了就是按位取反啊,所以反码是从下层映射上来的东西,我们为什么要研究它,就是因为它的物理太容易实现了,我们不得不研究它的性质,研究它与我们的补码的关系.结果,果不起然,关系密切着呢,是什么啊,反码加1就变补码了.这就是三大编码了,原码,反码,补码.1.原码正数的符号位为0,负数的符号位为1,其它位按照一般的方法来表示数的绝对值。
128的补码
128的补码-128的补码2010-10-24 10:29-128的补码2010年10月23日星期六10:538位定点整数的原码表示范围是-127到127 8位定点整数的补码表示范围是-128到127对上两句说明:用原码表示:01111111 8位有符号最大的数是127 11111111 8位有符号最小的数是-127 用补码表示:01111111 8位有符号最大的数是127 10000001 8位有符号最小的数是-127 但是还有一个更小的就是10000000把这个规定为-128的补码在8位长度下,-128的原码与反码都不存在,因为一个字节的有符号数的原码范围是:-127~+127,既然不存在-128的原码那么就无法求出-128的补码了,怎么办?前几天听汇编老师曲俊华讲过,-128这样的数很特殊,不是取反加一求补码。
-2^n是个特殊数(n为x数值位的长度):它补码的求法应按照公式进行运算: 如:-128"[-2^7]补"=(2^8)+(-2^7)=10000000原来还有更牛x的解释:一般的说法是负数的补码为其原码除符号位外取反然后总体加一,也就是说,要得到一个负数数的补码,要先知道这个负数的原码才行。
那么,问题出现了,在8位长度下,-128的原码与反码都不存在,127~+127,既然不存在-128的原码因为一个字节的有符号数的原码范围是:- 那么就无法求出-128的补码了,怎么办?其实,这个问题的实际意义是,既然说计算机内部的有符号整数都是补码,那么怎么才能有效的实现这一设计呢?潜台词是:根据上面由原码推导出补码的理论,如果是正数,计算机得到其原码,也就是得到了其补码(正数补码等同于原码),如果是负数,先得到其原码,然后再取反加一就可以了。
也就是说按这个思维设计编译器,或计算机电路,就可以了。
但是如果出现开始说的-128的补码问题,这个设计就不能工作了。
其实,在真正的设计中,这种获得负数补码的"取反加一"的方案根本没有实施过~拿现代的计算机举例,输入设备只有键盘,通过编辑器程序把键盘的扫描码变成ascii码存储起来,比如输入'a'就存储0x61,输入'5'就存储0x35,这些都是ascii码。
为什么计算机用补码存储数据?
为什么计算机用补码存储数据?在计算机内部,所有信息都是用二进制数串的形式表示的。
整数通常都有正负之分,计算机中的整数分为无符号的和带符号的。
无符号的整数用来表示0和正整数,带符号的证书可以表示所有的整数。
由于计算机中符号和数字一样,都必须用二进制数串来表示,因此,正负号也必须用0、1来表示。
通常我们用最高的有效位来表示数的符号(当用8位来表示一个整数时,第8位即为最高有效位,当用16位来表示一个整数时,第16位即为最高有效位。
)0表示正号、1表示负号,这种正负号数字化的机内表示形式就称为“机器数”,而相应的机器外部用正负号表示的数称为“真值”。
将一个真值表示成二进制字串的机器数的过程就称为编码。
无符号数没有原码、反码和补码一说。
只有带符号数才存在不同的编码方式。
带符号整数有原码、反码、补码等几种编码方式。
原码即直接将真值转换为其相应的二进制形式,而反码和补码是对原码进行某种转换编码方式。
正整数的原码、反码和补码都一样,负数的反码是对原码的除符号位外的其他位进行取反后的结果(取反即如果该位为0则变为1,而该位为1则变为0的操作)。
而补码是先求原码的反码,然后在反码的末尾位加1 后得到的结果,即补码是反码+1。
IBM-PC中带符号整数都采用补码形式表示。
(注意,只是带符号的整数采用补码存储表示的,浮点数另有其存储方式。
)采用补码的原因或好处如下,采用补码运算具有如下两个特征:1)因为使用补码可以将符号位和其他位统一处理,同时,减法也可以按加法来处理,即如果是补码表示的数,不管是加减法都直接用加法运算即可实现。
2)两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。
这样的运算有两个好处:1)使符号位能与有效值部分一起参加运算,从而简化运算规则。
从而可以简化运算器的结构,提高运算速度;(减法运算可以用加法运算表示出来。
)2)加法运算比减法运算更易于实现。
使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计。
原码的表示范围
原码的表示范围计算机中表示数值常常采用二进制,通常使用原码和补码表示。
我们在讨论计算机存储整数时,下面我们将探讨原码的表示范围及其相关信息。
原码是一种二进制表示方法,在这个方法中整数按照正负号位为数值的最高位,如果最高位为0,表示这个数是正数,如果最高位为1,表示这个数为负数。
原码是最直接的编码方式,非常直观,但是在对有符号数进行运算时会出现一些问题,比如加减法出现的进位或借位。
原码的表示范围很小,仅仅只有一个符号位,这个符号位是正数或负数的标志。
对于一个n位的原码数,其表示范围为[−2n-1+1, 2n-1-1]。
比如,一个8位的二进制原码数,其表示的数范围为[-127,127]。
在原码中,虽然使用一位表示符号,但由于要为数值留下足够的位数,因此整数的表达范围显得很小。
另外,原码的加减运算也比较麻烦,需要分别处理符号位和数值位。
因此,补码产生了。
补码是一种二进制表示方法,它通过对原码取反后加1来获取表示范围更大的负数,也使加减法更方便。
在补码中,负数的二进制表示不再是原码前面加一个1,而是使用正数的补码表示。
与原码相比,补码的表示范围更大,可以用相同位数来表示更大幅度的数字。
对于n位二进制补码表示,其表示范围为[−2n-1,2n-1-1]。
比如,8位的二进制补码范围为[-128,127]。
可以将原码和补码表示比较,发现它们的范围不同。
在原码中,正数和负数的范围是相同的,而在补码中,负数的表示范围比正数范围多一个单位。
这个多出来的范围是由于负数的补码前面多了一个1。
此外,补码的加减运算也更方便。
在补码中,减法转换为加法的形式,我们只需要将减数求补(用1减去减数的每一位,即按位取反),再加上被减数,然后计算出结果的补码即可。
对于补码范围的表示,需要注意的就是表示最小数或最大数的时候,可能会存在溢出的情况。
比如,8位二进制下的补码,可以表示在-128到127之间的数字,但在用补码表示-128的时候由于超出了表示范围,就会出现“溢出”的情况,即最高位变成了1。
原码、反码、补码详解!不懂的请看过来!(转)
原码、反码、补码详解!不懂的请看过来!(转)本篇⽂章讲解了计算机的原码、反码和补码,并且进⾏了深⼊探求了为何要使⽤反码和补码,以及更进⼀步的论证了为何可以⽤反码、补码的加法去计算原码的减法。
论证部分如有不对的地⽅请各位⽜⼈帮忙指正!希望本⽂对⼤家学习计算机基础有所帮助!⼀. 机器数和机器数的真值在学习原码,反码和补码之前,需要先了解机器数和真值的概念。
1、机器数⼀个数在计算机中的⼆进制表⽰形式,叫做这个数的机器数。
机器数是带符号的,在计算机⽤机器数的最⾼位存放符号,正数为0,负数为1。
⽐如,⼗进制中的数 +3 ,计算机字长为8位,转换成⼆进制就是0000 0011。
如果是 -3 ,就是 100 00011 。
那么,这⾥的 0000 0011 和 1000 0011 就是机器数。
2、机器数的真值因为第⼀位是符号位,所以机器数的形式值就不等于真正的数值。
例如上⾯的有符号数 1000 0011,其最⾼位1代表负,其真正数值是 -3,⽽不是形式值131(1000 0011转换成⼗进制等于131)。
所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1⼆. 原码, 反码, 补码的基础概念和计算⽅法在探求为何机器要使⽤补码之前,让我们先了解原码、反码和补码的概念。
对于⼀个数,计算机要使⽤⼀定的编码⽅式进⾏存储,原码、反码、补码是机器存储⼀个具体数字的编码⽅式。
1. 原码原码就是符号位加上真值的绝对值,即⽤第⼀位表⽰符号,其余位表⽰值。
⽐如:如果是8位⼆进制:[+1]原= 0000 0001[-1]原= 1000 0001第⼀位是符号位,因为第⼀位是符号位,所以8位⼆进制数的取值范围就是:(即第⼀位不表⽰值,只表⽰正负。
)[1111 1111 , 0111 1111]即[-127 , 127]原码是⼈脑最容易理解和计算的表⽰⽅式。
负数二进制
负的二进制数二进制算术需要理解的另一个方面是负数。
前面一直假定所有的数字都是正的。
从乐观的角度来看是这样,所以我们目前已对二进制数有了一半的认识。
但在实际中还会遇到负数,从悲观的角度来看,我们对二进制数的认识仅仅是一半。
在计算机中,是如何表示负数的?我们只能按照自己的意愿来处理二进制数字,所以解决方案必须是使用其中的一个二进制数字。
对于允许是负数的数值(称为带符号的数值),必须先确定一个固定的长度(换言之,就是二进制数字的位数),再把最左边的二进制数字设置为符号位。
必须固定位数,这样才能避免符号位与其他位的混淆。
因为计算机的内存由8位字节组成,所以二进制数字要存储在多个8位中(通常是2的幕),即有些数字是8位,有些数字是16位等。
只要知道每个数值的位数,就可以找到符号位,它应是最左边的那一位。
如果符号位是0,该数值就是正的,如果它是1,该数值就是负的。
似乎这就解决了问题,但实际上并非如此。
当两个整数相加时,计算机不应不检查两个数字是否为负。
我们希望使用常规的“加”来生成相应的结果。
如果把–8加到+12上,答案就应是+4。
如果用简化的解决方案来执行这一操作,也就是把正数的符号位设置为1,使它变成负数,再执行算术运算,并进行常规的进位,答案就是错误的:12转换为二进制: 0000 1100–8转换为二进制: 1000 1000如果把它们加起来,结果是 1001 0100。
答案是-20,这可不是我们希望的结果+4,它的二进制应是0000 0100。
此时读者会认为,“没有把符号作为另一个位”。
但是,在用计算机进行计算时,这是必须要考虑的。
因为计算机是哑巴,它们处理这种情况会出问题。
我们需要用另一种方式来表示负数。
下面看看计算机如何表示–8,即从+4中减去+12,得到正确的结果:+4转换为二进制: 0000 0100+12转换为二进制: 0000 1100从前者中减去后者,结果是 1111 1000。
对于右边的4位数字,必须借1,才能进行减法,这正是我们在执行十进制算术时所进行的操作。
8位二进位制原码补码反码的表示范围各是多少怎么算的
8位二进位制原码补码反码的表示范围各是多少怎么算的8位二进位制原码的表示范围:-127~+1278位二进位制反码的表示范围:-127~+1278位二进位制补码的表示范围:-128~+127n位二进位制原码和n位二进位制反码:-2^(n-1)-1~+2^(n-1)-1;n位二进位制补码:-2^(n-1)~+2^(n-1)-1。
为什么规定范围-128到127?而不是规定其他范围?因为8位数,除去一位符号位,每一位只有0或1,那就有128种情况,每种情况按权值计算,就是0到127,加上正负号,就是256个数,但是+0和-0取反加一后都是00000000,所以就是255个数,但是这样就会剩下一个10000000什么都不表示,但是10000000如果看作无符号数就是128,而且第一位是1,所以用来表示-128。
知道了吗?不要动不动就说规定的,任何事存在就有它的道理。
这些范围,不是算的,是规定的。
8位二进位制原码的表示范围:-127【1,1111111】~-0【1,000000】加上+127【0,1111111】~+0【0,0000000】一共256位8位二进位制反码的表示范围:-127【1,1111111】~-0【1,000000】加上+127【0,1111111】~+0【0,0000000】一共256位8位二进位制补码的表示范围:根据溢位进位抛弃-0(原码)【1,000000】(的补码)【0,0000000】= +0(原码)【0,0000000】(的补码)【0,00000000】向重合了,所以有255位。
(记住有256个)所以剩下1个补码【1,0000000】没有原码。
所以规定为(就好像做题时设x,代表变数一样)-128位其原码。
为什么8位二进位制的补码取值范围是-128~127八位二进位制正数的补码范围是0000 0000 ~ 0111 1111 即0 ~ 127,负数的补码范围是正数的原码0000 0000 ~ 0111 1111 取反加一(也可以理解为负数1000 0000 ~ 1111 1111化为反码末尾再加一)。
为什么8位的二进制补码范围是[-128,127]
为什么8位的二进制补码范围是-128-127,而不是-127-127呀?为什么差一个数呀?数值有正负之分,计算机就用一个数的最高位存放符号(0为正,1为负).这就是机器数的原码了.假设机器能处理的位数为8.即字长为1byte,原码能表示数值的范围为(-127~-0 +0~127)共256个.? 有了数值的表示方法就可以对数进行算术运算.但是很快就发现用带符号位的原码进行乘除运算时结果正确,而在加减运算的时候就出现了问题,如下: 假设字长为8bits( 1 )?10-? ( 1 )10?=? ( 1 )10?+ ( -1 )10?= ?( 0 )10(00000001)原?+ (10000001)原?= (10000010)原?= ( -2 )?显然不正确.? 因为在两个整数的加法运算中是没有问题的,于是就发现问题出现在带符号位的负数身上,对除符号位外的其余各位逐位取反就产生了反码.反码的取值空间和原码相同且一一对应. 下面是反码的减法运算:?( 1 )10?-? ( 1 )?10=? ( 1 )?10+ ( -1 )?10= ?( 0 )10?(00000001)?反+ (11111110)反?=? (11111111)反?=? ( -0 ) ?有问题.( 1 )10?-? ( 2)10?=? ( 1 )10?+ ( -2 )10?= ?( -1 )10(00000001)?反+ (11111101)反?=? (11111110)反?=? ( -1 )?正确问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的.(印度人首先将零作为标记并放入运算之中,包含有零号的印度数学和十进制计数对人类文明的贡献极大).于是就引入了补码概念. 负数的补码就是对反码加一,而正数不变,正数的原码反码补码是一样的.在补码中用(-128)代替了(-0),所以补码的表示范围为:(-128~0~127)共256个.注意:(-128)没有相对应的原码和反码, (-128) = (10000000)另一种解释:因为8位的二进制补码的第一位一定是1(11111111)补=-128虽然“-0”也是“0”,但根据正、反、补码体系,“-0”的补码和“+0”是不同的,这样就出现两个补码代表一个数值的情况。
十六进制补码和原码的转化
十六进制补码和原码的转化进行算法计算时,常常用到byte类型与十六进制之间的转化,一涉及到负数有时就犯迷糊,先整理记录下来。
1.首先,任何一个数或符号在计算机中,都是以二进制的形式存储的。
一个数在计算机中的二进制表示形式, 叫做这个数的机器数。
机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是。
如果是 -3 ,就是。
那么,这里的和就是机器数(但-3在计算中的实际存储中,并不是以的形式存在,详见3)。
因为第一位是符号位,所以机器数的形式值就不等于真正的数值。
例如上面的有符号数,其最高位1代表负,其真正数值是 -3 而不是形式值131(转换成十进制等于131)。
所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值= –000 0001 = –12.下面谈一下十进制、八进制与十六进制。
而现实中我们所熟悉的十进制数,可能是先人还没发明计算机之前的计算方式吧(呵呵,扯远了)。
后来有了计算机,单纯的使用二进制表示数,有时人闹反应出我们所熟悉的十进制数比较慢(反之,由十进制在人脑中隐射成二进制亦然),而实际情况中对于3位与8位的二进制经常出现,所以又有了8进制与16进制,而8进制的7正好对应二进制111,如下。
八进制二进制真值7 11177 111111777十六进制的f对应二进制的1111,转化很方便也很好反应,如下十六进制二进制真值F 1111FFFFF 111而十进制与二进制却没有这个形式上的直观反应,如十进制中的9对应二进制的1001.99对应二进制的1100011没有什么直观规律可言。
所以在二进制的基础之上又发明了8进制与16进制。
(以上纯属个人臆想,只是为了自己理解方面,不可作为论断来看,权当一个小论述吧)3.关于原码、补码、反码。
为什么8位二进制的补码取值范围是-128~127
为什么8位有符号数的范围为“-128 —+127”?(转载加补充)这是一个困惑了我几年的问题,从我N年前开始摸电脑时,就几乎在每一本C++教科书上都说,8位有符号的取值范围是-128~+127,为什么不是-127~+127呢,后来的java,int的聚值范围,再32位计算,-2^31 ~ +2^31-1。
原因没有在工作上或者是什么地方直接遇到它,所以我也一直忽略它,但心里总是有一根刺.直到刚才!!!!就是刚才,无聊之极,在看汇编的书时,又遇到它了,但一如以往,书上直接地,有心地,明显地绕过了这个问题,真是可恶啊.几经周折,终于把它搞清楚了:话说:用2^8来表示无符号整数的话,全世界的理解都是0 - 255了,那么,有符号呢? 用最高位表示符号,0为+,1为-,那么,正常的理解就是-127 至+127 了.这就是原码了,值得一提的是,原码的弱点,有2个0,即+0和-0,还有就是,进行异号相加或同号相减时,比较笨蛋,先要判断2个数的绝对值大小,然后进行加减操作,最后运算结果的符号还要与大的符号相同.于是乎,反码产生了,原因....略,反正,没过多久,反码就成为了过滤产物,也就是,后来补码出现了.补码的知识不说述,只说有关+127和-128的.官方的定义[-2^(n-1),2(n-1)-1],补码的0没有正负之分.原因呢?没有一本书上有说,这也是我这么火的原因,但通过思考,google,再思考,很快找到答案:首先,难不免干点白痴般地事情,穷举一下...正数,原码跟补码一样+127, 0111 1111+126, 0111 1110+125, 0111 1101...+4, 0000 0100+3, 0000 0011+2, 0000 0010+1, 0000 00010, 0000 0000 (无正负之分)下面是负数了,值,原码,符号位不变其它取反,+1-1, 1000 0001, 1111 1110, 1111 1111-2, 1000 0010, 1111 1101, 1111 1110-3, 1000 0011, 1111 1100, 1111 1101-4, 1000 0100, 1111 1011, 1111 1100-5, 1000 0101, 1111 1010, 1111 1011…-125, 1111 1101, 1000 0010, 1000 0011-126, 1111 1110, 1000 0001, 1000 0010-127, 1111 1111, 1000 0000, 1000 0001看出点什么了没有?如果没有,那么,给个提示, 再继续下去,下一个补码是什么呢?当然是-128, 先略过,再略过, 1000 00001000 0000,那么,它的原码是什么呢?从补码求原码的方法跟原码求补码是一样的先保留符号位其它求反: 1111 1111, 再加1:11000 0000, 超过了8位了对,用8位数的原码在这里已经无法表示了关键就在这里,补码1000 0000 为-128 是不用怀疑的(上面的穷举),那么,回到原码处, 它的原码也是1000 0000(超出的自动丢失),1000 0000 在原码表示什么呢? -0, 但补码却规定0没有正负之分转换一下思路,看看计算机里,是怎么运算的:对于负数,先取绝对值,然后求反,加一-128 -> 128 -> 1000 0000 -> 0111 1111 -> 1000 0000现在明确了吧.所以, 8位有符号的整数取值范围的补码表示1000 0000 到0000 0000, 再到0111 1111即-128 到0, 再到127最终-128 ~ +127以上穷举,希望对各位有需要的网友有用,不过据非官方传闻,那个-128的补码表示为80H,即:0到127 二进制为 00000000到01111111-128到-1 二进制为10000000到11111111记住就好。
什么是原码、反码、补码
[-1] = [10000001]原 = [11111110]反 = [11111111]补
对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
三. 为何要使用原码, 反码和补码
在开始深入学习前, 我的学习建议是先"死记硬背"上面的原码, 反码和补码的表示方式以及计算方法.
1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原
这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:
于是人们开始探索 将符号位参与运算, 并且只保留加法的方法. 首先来看原码:
计算十进制的表达式: 1-1=0
1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数.
一. 机器数和真值
在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.
1、机器数
一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.
比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。
x mod y = x - y L x / y J
计算机中数值的三种表示方法详解:原码,反码, 补码
计算机中数值的三种表示方法详解原码,反码,补码最近在学习软件评测师的知识,其中涉及到计算机的原码, 反码和补码等知识. 通过网上查阅资料,进行了深入学习,分享给大家。
本文主要从以下几点进行介绍:如何计算原码,反码,补码?为何要使用反码和补码?希望本文对大家学习计算机基础有所帮助一. 机器数和真值在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.1、机器数一个数在计算机中的二进制表示形式, 叫做这个数的机器数。
机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.比如,十进制中的数+3 ,计算机字长为8位,转换成二进制就是00000011。
如果是-3 ,就是10000011 。
那么,这里的00000011 和10000011 就是机器数。
2、真值因为第一位是符号位,所以机器数的形式值就不等于真正的数值。
例如上面的有符号数10000011,其最高位1代表负,其真正数值是-3 而不是形式值131(10000011转换成十进制等于131)。
所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
例:0000 0001的真值= +000 0001 = +1,1000 0001的真值= –000 0001 = –1二. 原码, 反码, 补码的基础概念和计算方法.计算机中的符号数有三种表示方法,即原码、反码和补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。
1. 原码原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:[+1]原 = 0000 0001[-1]原 = 1000 0001第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是: [1111 1111 , 0111 1111]即[-127 , 127]原码是人脑最容易理解和计算的表示方式.2. 反码反码的表示方法是:正数的反码是其本身负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.[+1] = [00000001]原 = [00000001]反[-1] = [10000001]原 = [11111110]反可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.3. 补码补码的表示方法是:正数的补码就是其本身负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)[+1] = [00000001]原 = [00000001]反 = [00000001]补[-1] = [10000001]原 = [11111110]反 = [11111111]补对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.简单总结以下,反码和补码的表示方式以及计算方法.对于正数,三种编码方式的结果都相同:正整数的原码、反码、补码完全一样,即符号位固定为0,数值位相同。
计算机工作原理-原码反码补码
定义●原码正数的符号位为0,负数的符号位为1,其它位按照一般的方法来表示数的绝对值。
用这样的表示方法得到的就是数的原码。
【例1】当机器字长为8位二进制数时:X=+1011011 [X]原码=01011011Y=-1011011 [Y]原码=11011011[+1]原码=00000001 [-1]原码=10000001[+127]原码=01111111 [-127]原码=11111111 原码表示的整数范围是:-(2n-1-1)~+(2n-1-1),其中n为机器字长。
则:8位二进制原码表示的整数范围是-127~+12716位二进制原码表示的整数范围是-32767~+32767●反码对于一个带符号的数来说,正数的反码与其原码相同,负数的反码为其原码除符号位以外的各位按位取反。
【例2】当机器字长为8位二进制数时:X=+1011011 [X]原码=01011011 [X]反码=01011011Y=-1011011 [Y]原码=11011011 [Y]反码=10100100[+1]反码=00000001 [-1]反码=11111110[+127]反码=01111111 [-127]反码=10000000负数的反码与负数的原码有很大的区别,反码通常用作求补码过程中的中间形式。
反码表示的整数范围与原码相同。
补码正数的补码与其原码相同,负数的补码为其反码在最低位加1。
引入补码以后,计算机中的加减运算都可以统一化为补码的加法运算,其符号位也参与运算。
【例3】(1)X=+1011011 (2)Y=-1011011(1)根据定义有:[X]原码=01011011 [X]补码=01011011(2)根据定义有:[Y]原码=11011011 [Y]反码=10100100[Y]补码=10100101补码表示的整数范围是-2n-1~+(2n-1-1),其中n为机器字长。
则:8位二进制补码表示的整数范围是-128~+127(-128 表示为10000000,无对应的原码和反码)16位二进制补码表示的整数范围是-32768~+32767当运算结果超出这个范围时,就不能正确表示数了,此时称为溢出。
计算机中数值的三种表示方法详解:原码,反码, 补码
计算机中数值的三种表示方法详解原码,反码,补码最近在学习软件评测师的知识,其中涉及到计算机的原码, 反码和补码等知识. 通过网上查阅资料,进行了深入学习,分享给大家。
本文主要从以下几点进行介绍:如何计算原码,反码,补码?为何要使用反码和补码?希望本文对大家学习计算机基础有所帮助一. 机器数和真值在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.1、机器数一个数在计算机中的二进制表示形式, 叫做这个数的机器数。
机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.比如,十进制中的数+3 ,计算机字长为8位,转换成二进制就是00000011。
如果是-3 ,就是10000011 。
那么,这里的00000011 和10000011 就是机器数。
2、真值因为第一位是符号位,所以机器数的形式值就不等于真正的数值。
例如上面的有符号数10000011,其最高位1代表负,其真正数值是-3 而不是形式值131(10000011转换成十进制等于131)。
所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
例:0000 0001的真值= +000 0001 = +1,1000 0001的真值= –000 0001 = –1二. 原码, 反码, 补码的基础概念和计算方法.计算机中的符号数有三种表示方法,即原码、反码和补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。
1. 原码原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:[+1]原 = 0000 0001[-1]原 = 1000 0001第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是: [1111 1111 , 0111 1111]即[-127 , 127]原码是人脑最容易理解和计算的表示方式.2. 反码反码的表示方法是:正数的反码是其本身负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.[+1] = [00000001]原 = [00000001]反[-1] = [10000001]原 = [11111110]反可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.3. 补码补码的表示方法是:正数的补码就是其本身负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)[+1] = [00000001]原 = [00000001]反 = [00000001]补[-1] = [10000001]原 = [11111110]反 = [11111111]补对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.简单总结以下,反码和补码的表示方式以及计算方法.对于正数,三种编码方式的结果都相同:正整数的原码、反码、补码完全一样,即符号位固定为0,数值位相同。
原码、反码、补码之间的相互关系
原码、反码、补码之间的相互关系1、10001的补码是取反后在再加1,也就是11110+1=11111;2、如果是11111变回原码呢?我们可以采取逆过程先减1,11111-1=11110,再取反变为10001;3、如果要是在补码变原码时先去反再加⼀呢?(就是问题中的说法)结果为11111先取反为10000,再加1,10000+1=10001。
这个结果与2是⼀样的,并且也是和1中的原码相吻合。
在取反前减1和在取反后加1的效果是⼀样的。
这就和-3-1=-(3+1)是⼀个道理。
计算机保存最原始的数字,也是没有正和负的数字,叫没符号数字如果我们在内存分配4位(bit)去存放⽆符号数字,是下⾯这样⼦的后来在⽣活中为了表⽰“⽋别⼈钱”这个概念,就从⽆符号数中,划分出了“正数”和“负数”正如上帝⼀挥⼿,从混沌中划分了“⽩天”与“⿊夜”为了表⽰正与负,⼈们发明了"原码",把⽣活应该有的正负概念,原原本本的表⽰出来把左边第⼀位腾出位置,存放符号,正⽤0来表⽰,负⽤1来表⽰但使⽤“原码”储存的⽅式,⽅便了看的⼈类,却苦了计算机我们希望(+1)和(-1)相加是0,但计算机只能算出0001+1001=1010 (-2)这不是我们想要的结果 (╯' - ')╯︵┻━┻另外⼀个问题,这⾥有⼀个(+0)和(-0)为了解决“正负相加等于0”的问题,在“原码”的基础上,⼈们发明了“反码”“反码”表⽰⽅式是⽤来处理负数的,符号位置不变,其余位置相反当“原码”变成“反码”时,完美的解决了“正负相加等于0”的问题过去的(+1)和(-1)相加,变成了0001+1101=1111,刚好反码表⽰⽅式中,1111象征-0⼈们总是进益求精,历史遗留下来的问题—— 有两个零存在,+0 和 -0我们希望只有⼀个0,所以发明了"补码",同样是针对"负数"做处理的"补码"的意思是,从原来"反码"的基础上,补充⼀个新的代码,(+1)我们的⽬标是,没有蛀⽛(-0)有得必有失,在补⼀位1的时候,要丢掉最⾼位我们要处理"反码"中的"-0",当1111再补上⼀个1之后,变成了10000,丢掉最⾼位就是0000,刚好和左边正数的0,完美融合掉了这样就解决了+0和-0同时存在的问题另外"正负数相加等于0"的问题,同样得到满⾜举例,3和(-3)相加,0011 + 1101 =10000,丢掉最⾼位,就是0000(0)同样有失必有得,我们失去了(-0) , 收获了(-8)以上就是"补码"的存在⽅式结论:保存正负数,不断改进⽅案后,选择了最好的"补码"⽅案⼆进制数在内存中以的形式存储。
原码、补码、反码的关系
原码、补码、反码的关系⼀. 机器数和真值在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.1、机器数⼀个数在计算机中的⼆进制表⽰形式, 叫做这个数的机器数。
机器数是带符号的,在计算机⽤⼀个数的最⾼位存放符号, 正数为0, 负数为1.⽐如,⼗进制中的数 +3 ,计算机字长为8位,转换成⼆进制就是00000011。
如果是 -3 ,就是 10000011 。
那么,这⾥的 00000011 和 10000011 就是机器数。
2、真值因为第⼀位是符号位,所以机器数的形式值就不等于真正的数值。
例如上⾯的有符号数 10000011,其最⾼位1代表负,其真正数值是 -3 ⽽不是形式值131(10000011转换成⼗进制等于131)。
所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1⼆. 原码, 反码, 补码的基础概念和计算⽅法.在探求为何机器要使⽤补码之前, 让我们先了解原码, 反码和补码的概念.对于⼀个数, 计算机要使⽤⼀定的编码⽅式进⾏存储. 原码, 反码, 补码是机器存储⼀个具体数字的编码⽅式.1. 原码原码就是符号位加上真值的绝对值, 即⽤第⼀位表⽰符号, 其余位表⽰值. ⽐如如果是8位⼆进制:[+1]原 = 0000 0001[-1]原 = 1000 0001第⼀位是符号位. 因为第⼀位是符号位, 所以8位⼆进制数的取值范围就是:[1111 1111 , 0111 1111]即[-127 , 127]原码是⼈脑最容易理解和计算的表⽰⽅式.2. 反码反码的表⽰⽅法是:正数的反码是其本⾝负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.[+1] = [00000001]原 = [00000001]反[-1] = [10000001]原 = [11111110]反可见如果⼀个反码表⽰的是负数, ⼈脑⽆法直观的看出来它的数值. 通常要将其转换成原码再计算.3. 补码补码的表⽰⽅法是:正数的补码就是其本⾝负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)[+1] = [00000001]原 = [00000001]反 = [00000001]补[-1] = [10000001]原 = [11111110]反 = [11111111]补对于负数, 补码表⽰⽅式也是⼈脑⽆法直观看出其数值的. 通常也需要转换成原码在计算其数值.三. 为何要使⽤原码, 反码和补码在开始深⼊学习前, 我的学习建议是先"死记硬背"上⾯的原码, 反码和补码的表⽰⽅式以及计算⽅法.现在我们知道了计算机可以有三种编码⽅式表⽰⼀个数. 对于正数因为三种编码⽅式的结果都相同:[+1] = [00000001]原 = [00000001]反 = [00000001]补所以不需要过多解释. 但是对于负数:[-1] = [10000001]原 = [11111110]反 = [11111111]补可见原码, 反码和补码是完全不同的. 既然原码才是被⼈脑直接识别并⽤于计算表⽰⽅式, 为何还会有反码和补码呢?⾸先, 因为⼈脑可以知道第⼀位是符号位, 在计算的时候我们会根据符号位, 选择对真值区域的加减. (真值的概念在本⽂最开头). 但是对于计算机, 加减乘数已经是最基础的运算, 要设计的尽量简单. 计算机辨别"符号位"显然会让计算机的基础电路设计变得⼗分复杂! 于是⼈们想出了将符号位也参与运算的⽅法. 我们知道, 根据运算法则减去⼀个正数等于加上⼀个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法⽽没有减法,这样计算机运算的设计就更简单了.于是⼈们开始探索将符号位参与运算, 并且只保留加法的⽅法. ⾸先来看原码:计算⼗进制的表达式: 1-1=01 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2如果⽤原码表⽰, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使⽤原码表⽰⼀个数.为了解决原码做减法的问题, 出现了反码:计算⼗进制的表达式: 1-1=01 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0发现⽤反码计算减法, 结果的真值部分是正确的. ⽽唯⼀的问题其实就出现在"0"这个特殊的数值上. 虽然⼈们理解上+0和-0是⼀样的, 但是0带符号是没有任何意义的. ⽽且会有[0000 0000]原和[1000 0000]原两个编码表⽰0.于是补码的出现, 解决了0的符号以及两个编码的问题:1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原这样0⽤[0000 0000]表⽰, ⽽以前出现问题的-0则不存在了.⽽且可以⽤[1000 0000]表⽰-128:(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补-1-127的结果应该是-128, 在⽤补码运算的结果中, [1000 0000]补就是-128. 但是注意因为实际上是使⽤以前的-0的补码来表⽰-128, 所以-128并没有原码和反码表⽰.(对-128的补码表⽰[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)使⽤补码, 不仅仅修复了0的符号以及存在两个编码的问题, ⽽且还能够多表⽰⼀个最低数. 这就是为什么8位⼆进制, 使⽤原码或反码表⽰的范围为[-127, +127], ⽽使⽤补码表⽰的范围为[-128, 127].因为机器使⽤补码, 所以对于编程中常⽤到的32位int类型, 可以表⽰范围是: [-231, 231-1] 因为第⼀位表⽰的是符号位.⽽使⽤补码表⽰时⼜可以多保存⼀个最⼩值.四原码, 反码, 补码再深⼊计算机巧妙地把符号位参与运算, 并且将减法变成了加法, 背后蕴含了怎样的数学原理呢?将钟表想象成是⼀个1位的12进制数. 如果当前时间是6点, 我希望将时间设置成4点, 需要怎么做呢?我们可以:1. 往回拨2个⼩时: 6 - 2 = 42. 往前拨10个⼩时: (6 + 10) mod 12 = 43. 往前拨10+12=22个⼩时: (6+22) mod 12 =42,3⽅法中的mod是指取模操作, 16 mod 12 =4 即⽤16除以12后的余数是4.所以钟表往回拨(减法)的结果可以⽤往前拨(加法)替代!现在的焦点就落在了如何⽤⼀个正数, 来替代⼀个负数. 上⾯的例⼦我们能感觉出来⼀些端倪, 发现⼀些规律. 但是数学是严谨的. 不能靠感觉.⾸先介绍⼀个数学中相关的概念: 同余同余的概念两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于模m同余记作 a ≡ b (mod m)读作 a 与 b 关于模 m 同余。
8bitadc设计时存在负值的原因
8bitadc设计时存在负值的原因以8位ADC设计时存在负值的原因在数字电路中,ADC(Analog-to-Digital Converter)是将模拟信号转换为数字信号的重要组件。
8位ADC即表示其可以将模拟信号转换为8位的二进制数字信号。
然而,在设计8位ADC时,我们会发现其输出值范围为0-255,即无法表示负值。
那么,为什么8位ADC设计时存在负值呢?1. ADC的工作原理ADC的工作原理是将模拟信号分成若干个等间隔的量化区间,然后根据模拟信号的大小将其映射到对应的量化区间,并将量化区间的编号转换为相应的二进制数字。
例如,对于8位ADC,它将模拟信号分成256个等间隔的区间,每个区间对应一个8位的二进制数字。
2. ADC的输出范围对于8位ADC而言,其输出范围为0-255,即其输出值只能在这个范围内取值。
这是因为8位的二进制数字可以表示的最大值为11111111,即十进制的255。
而无法表示负值的原因则是因为8位ADC没有设计用于表示负值的位。
3. 无符号数和有符号数在计算机系统中,数字可以用无符号数和有符号数表示。
无符号数只能表示非负数,而有符号数可以表示负数和非负数。
由于8位ADC设计时没有考虑有符号数的表示,因此其输出范围限制在了非负数范围内。
4. 补码表示负数在计算机系统中,负数一般使用补码(Two's Complement)表示。
补码是一种用于表示有符号数的编码方式,其中最高位表示符号位,0表示正数,1表示负数。
使用补码表示负数的好处是可以使用加法器来进行正数和负数的加减运算,简化了电路设计。
5. 扩展位要想在8位ADC中表示负值,一种常见的做法是使用扩展位。
扩展位是指在原有位数的基础上增加一个用于表示符号的位。
例如,在8位ADC中,可以使用最高位作为扩展位,0表示正数,1表示负数。
这样一来,8位ADC就可以表示-128至127的整数范围。
6. 压缩编码除了使用扩展位外,还可以使用压缩编码的方式来表示负值。
一个数的原码,反码,补码??
基本概念在计算机内部表示二进制数的方法称为数值编码,把一个数及其符号在机器中的表示加以数值化,称为机器数。
机器数所代表的数称为数的真值。
表示一个机器数,应考虑以下三个因素:1.机器数的范围字长为8位,无符号整数的最大值是(11111111)B=(255)D,此时机器数的范围是0~255。
字长为16位,无符号整数的最大值是(1111111111111111)B=(FFFF)H=(65535)D 此时机器数的范围是0~65535。
2.机器数的符号在算术运算中,数据是有正有负的,将这类数据称为带符号数。
为了在计算机中正确地表示带符号数,通常规定每个字长的最高位为符号位,并用0表示正数,用1表示负数。
3.机器数中小数点的位置在机器中,小数点的位置通常有两种约定:一种规定小数点的位置固定不变,这时的机器数称为“定点数”。
另一种规定小数点的位置可以浮动,这时的机器数称为“浮点数”。
4.原码正数的符号位为0,负数的符号位为1,其它位按照一般的方法来表示数的绝对值。
用这样的表示方法得到的就是数的原码。
【例1】当机器字长为8位二进制数时:X=+1011011 [X]原码=01011011Y=—1011011 [Y]原码=11011011[+1]原码=00000001 [-1]原码=10000001[+127]原码=01111111 [-127]原码=11111111原码表示的整数范围是:-(2n-1-1)~+(2n-1-1),其中n为机器字长。
则:8位二进制原码表示的整数范围是-127~+12716位二进制原码表示的整数范围是-32767~+327675.反码对于一个带符号的数来说,正数的反码与其原码相同,负数的反码为其原码除符号位以外的各位按位取反。
【例2.14】当机器字长为8位二进制数时:X=+1011011 [X]原码=01011011 [X]反码=01011011Y=-1011011 [Y]原码=11011011 [Y]反码=10100100[+1]反码=00000001 [-1]反码=11111110[+127]反码=01111111 [-127]反码=10000000负数的反码与负数的原码有很大的区别,反码通常用作求补码过程中的中间形式。
负数在计算机中都是以补码形式存在
负数在计算机中都是以补码形式存在负数在计算机中是以补码的形式储存的注意:本文为了简化运算,二进制数都是用一个字节——8个二进制位说明1 一些概念在进行问题探究之前,先了解一些概念1.1 原码原码就是符号位加上真值的绝对值,即8位二进制数的第一位是符号位,其余位表示值+1(原) = 0000 0001-1(原) = 1000 0001第一位表示正负号,所以8位二进制数的取值范围是[1111 1111 , 0111 1111]即[-127,127]1.2 反码正负数的反码规则不一样正数的反码就是其本身负数的反码就是,在原码的基础上,符号位不变,其余位取反+1 = [0000 0001]原= [0000 0001]反-1 = [1000 0001]原= [1111 1110]反1.3 补码补码的计算规则为正数的补码就是其本身负数的补码就是在其反码的基础上+1+1 = [0000 0001]原= [0000 0001]反= [0000 0001]补-1 = [1000 0001]原= [1111 1110]反= [1111 1111]补2 为何这么复杂从上面我们可以知道,负数的原码、反码、补码是很不一样的,这样设计的好处是方便计算机做减法首先,因为人可以轻松知道第一位是符号位,在计算的时候我们会根据符号位,选择对真值区域的加减。
但是要让计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂!于是就想出了将符号位也参与运算的方法。
我们知道,根据运算法则减去一个正数等于加上一个负数,即:1 - 1 = 1 + (-1) = 0 ,所以机器可以只有加法而没有减法,这样计算机运算的设计就更简单了于是开始探索将符号位参与运算,并且只保留加法的方法以1-1=0为例原码1 - 1 = 1 + (-1) =[0000 0001]原---------------------= [1000 0010]原= -2如果用原码表示,让符号位也参与计算,显然对于减法来说,结果是不正确的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
为什么8位的二进制补码范围是-128-127,而不是-127-127呀?为什么差一个数呀?
数值有正负之分,计算机就用一个数的最高位存放符号(0为正,1为负).这就是机器数的原码了.假设机器能处理的位数为8.即字长为1byte,原码能表示数值的范围为
(-127~-0 +0~127)共256个.
? 有了数值的表示方法就可以对数进行算术运算.但是很快就发现用带符号位的原码进行乘除运算时结果正确,而在加减运算的时候就出现了问题,如下: 假设字长为8bits
( 1 )?10-? ( 1 )10?=? ( 1 )10?+ ( -1 )10?= ?( 0 )10
(00000001)原?+ (10000001)原?= (10000010)原?= ( -2 )?显然不正确.
? 因为在两个整数的加法运算中是没有问题的,于是就发现问题出现在带符号位的负数身上,对除符号位外的其余各位逐位取反就产生了反码.反码的取值空间和原码相同且一一对应. 下面是反码的减法运算:
?( 1 )10?-? ( 1 )?10=? ( 1 )?10+ ( -1 )?10= ?( 0 )10
?(00000001)?反+ (11111110)反?=? (11111111)反?=? ( -0 ) ?有问题.
( 1 )10?-? ( 2)10?=? ( 1 )10?+ ( -2 )10?= ?( -1 )10
(00000001)?反+ (11111101)反?=? (11111110)反?=? ( -1 )?正确
问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的.(印度人首先将零作为标记并放入运算之中,包含有零号的印度数学和十进制计数对人类文明的贡献极大).
于是就引入了补码概念. 负数的补码就是对反码加一,而正数不变,正数的原码反码补码是一样的.在补码中用(-128)代替了(-0),所以补码的表示范围为:
(-128~0~127)共256个.
注意:(-128)没有相对应的原码和反码, (-128) = (10000000)
另一种解释:
因为8位的二进制补码的第一位一定是1
(11111111)补=-128
虽然“-0”也是“0”,但根据正、反、补码体系,“-0”的补码和“+0”是不同的,这样就出现两个补码代表一个数值的情况。
为了将补码与数字一一对应,所以人为规定“0”一律用“+0”代ct9789:
你好。
指针: 其实指针这个概念在谭浩强的<C程序设计>这本书上是这样说的,指针就是地址,指针值就是地址值。
指针变量就是存放指针的
变量,所以一定不要将指针与指针变量搞混淆了。
指针仅仅是一个地址值,而指针变量就是存放指针(也就是地址的变量)
指针的定义:
例如整型指针: int *p;p是一个指向int类型数据的指针变量。
里面存放的地址(也就是指针)是一个int类型变量的地址。
指针变量时
有类型的,例如p的类型就是int *表示p是一个指向int类型的指针变量。
如何知道一个指针变量的类型呢,最简单的方法就是去掉变
量定义语句中的变量名,剩下的部分就是其类型,这种方法适用于所有的变量定义,例如int a;a的类型是int 。
int b[10];b的类
型是int[]表示是一个数组(关于数组类型这里不谈,因为这个问题很微妙,其实在c、c++中没有数组类型这个概念,包括函数类型也
是一样的),int *c;c的类型是int *。
int ** d;d的类型就是int **;所以通过这种方法来判断一个变量的类型是很方便的。
说道指针变量,我们必须说到得有几个方面。
1.指针类型。
这个很重要,一个指针是有类型的,也就是一个地址是有类型的。
具体说是某一个地址会指向不同类型的数据,这是不一样的,例如
int *p;p是指向int型数据。
double*p1;p1是指向double型数据。
但是p和p1本身在内存中占用的空间是4个字节(对于32位的系统来说
),如果是在TC中编译c程序,应该是2个字节了(dos操作系统是16位的)。
有人说地址不就是一个值吗,类似于0xfffdddcc这样的地址
数值,为什么还分什么类型呢,我要说的是这个关系很大。
我们知道指针是有运算的,int *p=&a;那么p++到底加了多少呢,不要以为
是将p里面的地址值加了1,这是完全想当然。
实际上加了sizeof(int)这么多个字节。
也就是说加了一个int元素应该占用的字节,这
样在数组中我们可以通过这种方式从上一个元素很方便的让指针变量指向下一个元素。
p+5的话实际上是加了p+sizeof(int)*5这么多
个字节。
另外一点事指针的类型决定了当指针解引用的时候其所以指向的内存单元中的二进制数据如何解释的问题。
例如int *p=&a;
那么(*p)取得的数字就是一个整型数据,如果(*((char *)p))得到的就是一个字符型数据了。
p本来指向的是int型数据(有4个字节)的
首地址,如果将其强制转换为一个指向char类型的指针变量,那么在解引用的时候只取第一个字节的数据,并将其解释为一个ascii码
代表的字符。
还有如果是一个指向函数的指针变量,我们可以通过此指针变量直接调用函数。
例如int(*function)(int);此时
表。
同时为了充分利用资源,就将原来本应该表示“-0”的补码规定为代表-128。