引入带符号数的表示方法是为了能够区分正数和负数,并且可以进行加、减等数学运算。在计算机中,常见的带符号数表示方法有原码、反码和补码。
一.原码、反码与补码的表示
①引入
原码、反码和补码是计算机领域中的概念,用于表示数字的二进制形式。
然而,原码存在着几个问题。首先,它无法进行加、减运算,因为当两个数字相加时,可能会出现进位的情况,进位会改变符号位,导致结果不正确。其次,原码存在着两个零,+0和-0,带来了混淆和不便。
为了解决这些问题,人们引入了反码和补码。
反码的加、减运算规则比较简单,但是它仍然存在着两个零的问题。
为了解决这个问题,人们引入了补码。
现代计算机通常使用补码来进行数字的二进制表示和运算。在补码中,正数的二进制数和原码一样,而负数的二进制数与原码不同。这是因为补码使用补数的方式来表示负数,比原码和反码更加高效和便捷。
②原码
先看看专业说法:原码是最简单的带符号表示方法,其中最高位表示符号位,0表示正数,1表示负数,其余位表示数值。但是原码表示法存在“0”的两种表示方法(+0和-0),并且负数的加减法比较复杂。
说人话,就是:
这是一种计算机中对数字的二进制表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位为数值本身(二进制的)。
举个例子:
十进制中的2的原码是 00000010
十进制中的-5的原码是 10000101
③反码
反码是为了解决原码中的两个0表示问题而提出的一种表示方法。负数的反码是对其对应正数的原码按位取反得到的,其中最高位仍然表示符号。反码表示法虽然解决了“0”的两种表示方法的问题,但是仍然存在减法的进位问题。
对于正数,反码与原码相同,即二进制表示不变,仍然为自身的原码。
而对于负数,反码的表示方式是符号位不变,将原码的所有位取反,即0变为1,1变为0
举个例子:
10的反码为001010
-10的反码为110101。
④补码
补码是目前计算机中最常用的带符号数表示方法。补码将负数的表示变为对其对应正数的补数表示。其中,正数的补码与原码相同,而负数的补码是其对应正数的原码按位取反后加1得到的。补码表示法解决了原码和反码中的问题,可以进行简单的加减法运算。同时,由于补码的表示是唯一的,计算机中只需要一套加减电路即可实现正负数的加减运算。
对于一个正数,与原码相同。
对于一个负数,它的补码是将其绝对值的二进制表示按位取反(0变为1,1变为0),然后加1【即它的反码加一】。这样,就能得到负数的二进制表示。
举个例子
十进制中3补码表示为0011
十进制中-3的补码表示为1101
二. 关于运算
在这之中,补码的运算是最方便、最实用、最广泛的,因此这里仅介绍补码的运算。
【例1】(+18)+(+15)
解:
00010010 [+18]补
+ 00001111 [+15]补
= 00100001 [+33]补
从这可知,此加法如彼加法,都按照加法法则。同位相加,逢二进一(二进制)。
【例2】(-18)+(+15)
11101110 [+18]补
+ 00001111 [-15]补
= 00000011 [+3]补
按照上述规律,这个的结果应该是100000011.但这里只有8位啊,如何是好?这里就牵扯出了另外一个规律——符号位的进位自动消失。
总而言之,有两大规律:
1)同位相加,逢二进一
2)符号位的进位自动消失
三.数的浮点表示
先以十进制数37为例:
显然,浮点数由两部分组成,N=。
其中,S为数N的符号和有效数位。而在中,10为十进制的基数。
同理,在二进制中,有N=*s
四.c++中表示进制数
很简单,自己看吧。
①八进制
以0开头即可。
//以0开头表示8进制
int a=010;
②16进制
以0X开头即可
int b=0x1A;
③科学计数法
注意:为浮点类型!
en表示10的n次方。
举个例子:
double a=3e5;
这个就是3*10^5。
综合
//以0开头表示8进制
int a=010;
//打印时以10进制打印
cout<<a<<endl;
//以0x开头表示16进制
int b=0x1A;
cout<<b<<en
//科学计数法
double d=1e-2;
cout<<d<<end1;
五.练习
鼠标按住拖动查看答案。
(1)一个有符号整数的二进制补码为1111111111101101,则其原码对应的10进制为-19
(2)一个有符号整数的二进制原码为1011010,则其反码为1100101,补码为1100110
(3)一个10进制整数—2,如果表达为带符号的8位2进制,那么其原码为10000010,反码为11111101,补码为11111110