原码
我们在初中时学的正负号,它们长得和加减号一样。比如:+5 表示正5,正号可以省略。负5写成-5, 负号不可以省略。
计算机中,一切数据都是用0和1表示, 正负号也是如此,0表示正号,1表示负号。
一个整数(int)是4个字节,也就是有32位,当仅考虑正整数时,32位都用来表示绝对值的大小,但现在我们需要考虑正负,所以,很自然的,我们要占用一个位来表示正负号。这样,就只剩下31位来表达数的绝对值大小。并且,就像-5中的负号写在最左边一样,计算机采用最左边的那位——专业一点称为:最高位——来表示正负号,重复一下:0表示正号,1表示负号。
(作业:请思考,为什么要用0,而不是1来表示正号?)
如果仅仅根据以上的知识,我们先可以想一下整数中,+1 和 -1 如何用二进制表示(纯粹为了不眼晕,这次我每个字节间加一个空隔):
00000000 00000000 00000000 00000001 (+1)
10000000 00000000 00000000 00000001 (-1)
区别就是最高位,1个是0,表示正号,1个是1,表示负号……除了这32位实在太长了些以外,一切都很直观嘛!红色的0表示正号,红色的1表示负号。这就是二进制的原码的表示法。
有关计算机正负表达的问题,似乎就这样搞定了,传说中的二进制也没有什么复杂的嘛……且慢!请回想一下,我们为什么要采用二进制?原因在于机器“喜欢”读二进制。所以在最高位用0或1来表示正负的方法,对人倒是直观,但机器却有怨言。
首先来看,0 这个数如何表达?代数老师教育我们,0是个两面派,+0 和 -0 都是0。当用原码来表达0时,这一点也得到直观的体现,请看:
00000000 00000000 00000000 00000000 (+0)
10000000 00000000 00000000 00000000 (-0)
计算机最喜欢的事是“确定”的事,最不喜欢的是“不确定”的事。所以,在“机器语言”这个层面上,对一个数有两种表达方法,这是不可接受的。
这里我们要抬杠一下,说:机器又不是人,它没有感情,我们就强制这样规定不就得了?
真正不能接受的,是运行效率。一个数字有两种表达方法,会造成计算机在判断一个数是不是0时,需要判断两次。
另一个问题就更严重了——在说这个严重问题之前,我们先复习一下小学算术课的竖式加法,请注意,时光倒流,我们回到小学的十进制年代:
123
234 +
----------
347
没有哪位看不懂这个竖式吧?下面我们会遇上好几次这样的竖式,重要的变化是除非特别说明,否则其中加数1、加数2以及和,都是二进制的。并且为了大家计算方便,需要时,我们会在二进制后面,添加一对括号(),其内写上对应的十进制数,或者更详细的说明。
现在来说那个严重问题。假设有+1和-1两个数,计算机如果要相加这两个数,结果将不正确:
00000000 00000000 00000000 00000001 (+1)
10000000 00000000 00000000 00000001 (-1) +
——————————————————----
10000000 00000000 00000000 00000010 (-2)
算出的错误结果是 -2。显然,采用“原码”的话,简单的将各位相加并不能得出正确的结果。相反,必须将用于表示正负号的最高位,和其它位分别处理。由于计算机可处理的最小内存单位是字节这一,对单独一位进行处理,又是一件不利于性能的事情。
事情如何解决,如果是让我来处理,恐怕我没有答案,还好当初的计算机先辈都是数学专家。他们想到了用“补码”来表达负数的这样一个“神奇的”方法。
反码和补码
反码和补码,都仅对负整数而言。对于正整数,我们坚持用原码表示,或才可以认为,正整数的原码、反码和补码,都一个样(就是原码)。
什么叫补码?我们得先从“反码”说起。所谓的反码,就是指对于在负数的原码的基础上,除去最高位以外,其它位全部取反,而取反的意思,就是如果原来是1,变成0;原来是0,则变成1的过程。
假设有一个数,-1,用原码表示,则为:
原码:10000000 00000000 00000000 00000001
反码:11111111 11111111 11111111 11111110
反码中,红色的1是保持不变的符号位(负号);蓝色的1或0,则是原码中对应位的取反所得。这就是-1的反码表示法。但这并不是我们要的最终结果。我们还需要进一步将反补变换为补码。
再强调一次:正整数的反码表示法不需要进行转换,它等同于原码。现在我们来考虑,如果采用反码,正负零的表示法分别是什么:
00000000 00000000 00000000 00000000 (+0的反码,没变,还是原码)
11111111 11111111 11111111 11111111 (-0的反码,全是1)
结论是用反码表达,0仍然有两种表示法,并且看上去差别更大了……,因此我们说了,反码只是临时产物,最终我们要的补码。
这个神秘的补码如何表达呢?其实很简单,有个公式:补码 = 反码 + 1。
当然,我们仍然要强调一下,对于正整数,补码就是原码。所以+0的补码仍然是0000 0000 0000 0000。而-0呢?它等它的反码加1,所以就是:
11111111 11111111 11111111 11111111 (负0的反码)
00000000 00000000 00000000 00000001 (正1) +
-----------------------------------------------------
00000000 00000000 00000000 00000000 (0)
可能你一下子有些反应不过来?为什么结果全是0了呢?我们说过了,二进制的世界里,数字只有0和1,因此相加时,肯定是逢2进1。如果你对“逢2进1”这个词有些似懂非懂,让我们想想十进制里的“逢10进1吧”,想像999 + 1 这个算式,写在竖式是:
999
1 +
-------------------
1000
按照这个规则,你再算一下上面的那个竖式:
11111111 11111111 11111111 11111111 (负0的反码)
00000000 00000000 00000000 00000001 (正1) +
-----------------------------------------------------
100000000 00000000 00000000 00000000 (最前面有个1啊?)
最前面,不是有一个1吗?是有个1,但是这个1不在实际运行结果中,因为一个int占用4个字节,最多只能放得下32位我们所看到那个“最高位”的1,已经是超出32位了。就像一个水杯,最多只能放1升水,你再往里倒,只能“溢出”——啊,没错,请记住“溢出”这个计算机术语!
小时候,小伙伴间经常玩这种游戏:你说1,他就说2,你说999,他就说1000,你说1万,他就说1万零1……反正无论你说个多大的数,他就说一个比你大1的数,真是气倒我们……今天,我们学习了二进制,这种游戏可以有个结束了!计算机中的数据是要占用内存资源的。对于一个整数,当你说出“11111111 11111111 11111111 11111111”这个数时,对方就只能闭嘴了,因为若是在这个数上再加1,结果将是:0。
看看我们扯出一大堆话,稍稍回归一下,用补码表示时,正负零是不是一致的?正0自然是32个0,而负0呢?如前面所罗嗦的,它通过负0的反码,再加上1,得到补码,正好也是32个0。
第一个问题解决了,用补码表示时,0的正负数表达方法得到的结果一致!
(作业:请写出以下几个十进制整数的补码:-1、5、-5、-12、-302)
第二个问题,+1 加上 -1,运算过程是否简捷,结果是否正确。
00000000 00000000 00000000 00000001 (+1,补码就是原码)
11111111 11111111 11111111 11111111 (负1的补码) +
------------------------------------------------------------
00000000 00000000 00000000 00000000 (0)
运算过程就是简单把逐位相加,进位,运算结果:(+1) + (-1) = 0。完全正确!原来,第一个问题和第二个问题用到的竖式,是那么的相像。a+b 等于 b+a,加法交换率,我们很小就学会了。不过在这里,它们各有自己的代表的意义。
另外,我们也发现,原来在计算机整数运算中,并不需要特别的减法,仅需把减法换成对减数取负后的加法即可。比如9 - 8的运算过程,就是9 + (-8)的过程。
分享到:
相关推荐
- **原码**:直接用二进制表示整数,最高位表示符号(0为正,1为负)。 - **反码**:正数的反码等于其原码;负数的反码等于其原码除了最高位外其余位取反。 - **补码**:正数的补码等于其原码;负数的补码等于其反码...
这通常涉及将e视为二进制数,如果e为负,则需要进行二进制补码操作。 4. **规范化**:如果尾数在转换后以0开头,需要通过调整指数并移除这些零来规范化。这可能会导致指数增加或减少,但不会改变浮点数的值。 5. *...
二进制数的四种表示形式——原码、反码、补码和移码,主要用于存储和运算整数。原码直接表示数值,正数的符号位为0,负数的符号位为1。反码表示负数时,除了符号位不变,其余各位按位取反,但0的原码和反码相同。...
书中解释了如何将十进制数分解为二进制形式,以及为什么计算机选择使用二进制——主要因为它非常适合电子电路的开/关状态表示。 此外,书中还讨论了基数的概念,不同的基数对应着不同的计数系统。基数决定了数字...
例如,正整数16在二进制中表示为0000000000010000,而负整数-16则表示为1111111111110000。这种表示法允许使用相同的位模式表示正负数,便于计算。实验中还提到了最大数32767(0111111111111111)和最小数-32768...
整型包括正整数和负整数,可以用二进制、八进制、十进制和十六进制表示。例如,二进制表示前缀是0b或0B,八进制是0o或0O,十六进制是0x或0X。浮点型由整数部分和小数部分构成,如1.23、3.14。复数则由实部和虚部组成...
“浮点数的二进制存储方式及转换.doc”文档很可能是详细解析了这些概念,并可能包含具体的例子和图表,帮助读者直观地理解浮点数的二进制表示以及如何进行转换。通过深入学习该文档,你可以更深入地理解浮点数在...
正整数在这三种表示中的形式相同,而负整数则不同。原码直接表示符号,反码是原码数值位取反,补码是反码最低位加1。零的表示有两种形式:正零和负零。 运算器是计算机硬件中的重要部件,负责执行算术和逻辑运算。...
同时,二进制运算规则——加法和乘法——非常直接,便于计算机快速执行。此外,二进制数的0和1与逻辑代数中的真值对应,使得逻辑运算和数据处理变得更加便捷。二进制和十进制间的转换可以通过特定的算法完成,例如...
二进制系统的进位方法是逢二进位,其位权为2的幂次方,从右向左依次是2的负次方,正次方,直到达到所需表达数值的位数。在二进制系统中,每一个位置上的数字只有0和1两种状态,非常适合用电子设备来实现,因为电子...
在二进制表示法中,正数的补码与原码相同;而负数的补码则是通过对该数的绝对值取反后再加1获得。补码的主要优点在于简化了计算机中的算术运算,尤其是加减运算。 #### 三、补码求取方法 **1. 方法一:取反加一法**...
然而,计算机科学中广泛使用的是二进制,因为它只需要两个符号——0和1,这与电子元件的两种稳定状态(如开/关)相对应。二进制的简单性使得它成为计算机处理信息的基础。 在转换过程中,有两种主要的方法:将十...
十进制 → 二进制的转换:整数部分:除2取余;小数部分:乘2取整。 十进制 → 十六进制的转换:整数部分:除16取余;小数部分:乘16取整。 (3)二进制与十六进制数之间的转换:用4位二进制数表示1位十六...
参数和返回值要求如下:参数 z 是长度不超过 8 的字符串,表示的是一个二进制整数;z 对应的真实值的符号可能是+或-,也可能没有,如没有,表示是正数,如’-1001’、’+101’、'101’都是 z 可能的取值;函数的...
一个负整数,当用原码、反码、补码表示时,符号位都固定为 1,用二进制表示的数位值都不相同,表示方法有所不同。 六、定点数和浮点数的加、减法运算 定点数和浮点数的加、减法运算可以使用变形补码计算,需要注意...
二进制数转换为十进制数、其他进制间的转换,以及十进制数转换为二进制数(整数用除2取余法,小数用乘2取整法)。 2. 二进制数在计算机内有多种表示形式,包括机器数(定点数和浮点数)。定点数分为带符号和不带符号...
- **二进制与十六进制数之间的转换**:用 4 位二进制数表示 1 位十六进制数。 - **无符号数二进制的运算**(见教材 P5) - **二进制数的逻辑运算特点**:按位运算,无进借位 - **与运算**:只有 A、B 变量皆为 1...
- 十进制转二进制:整数部分用“除2取余”法,小数部分用“乘2取整”法。 这些知识点构成了计算机组成原理的基础,理解和掌握它们对于深入学习计算机系统至关重要。在实际应用中,这些原理被广泛应用于软件开发、...