在计算机中,定点数有三种表示方法原码,反码和补码
原码:
任何一个正数都可以转换成0和1的形式,然后以二进制的形式存放在电脑里面,一个占8个字节的存储单元,可以存入的无符号的整数的范围是0到255,总共256个数。
1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
负数在计算机中的存放方法与正数一样,只不过加了一个符号位。例如一个占8个字节的存储单元,它能存放的有符号的整数范围是-127到正127,共255个数。它把第一位留出来,用作符号位。如果第一位是0,那么代表是正数。是1则代表是负数。
例如上图中,10001001 代表的是-9,第一个1(标记为红色的),是符号位,代表这个数是负数。
例如: 10001000 代表-8
00001000 代表+8
反码:
正数的反码是它本身。负数的反码,是它的绝对值的原码取反,取反。也就是1变成0,0变成1.
例如:-8的反码是 11110111
具体求解过程,-8的绝对值是+8,+8的原码是 00001000,直接按位取反,就变成了11110111
在网上,别人讲到这个地方的时候,总说取反的时候要把符号位带上,有时说得不清楚,让人混淆。其实带符号位取反可以,也可以不带符号位取反,取反后再加上符号位。例如上面的,是带符号位取反的。下面我们不带符号位取反(不带符号位取反,也就是不管符号位,把符号位放在一边)。
不带符号位取反的话,那么我们只看后面的7位。-8的原码为10001000,我们只看后面的7位,那就是0001000,我们把这7位取反得到1110111.因为我们要求-8的反码,那么在需要在上面求出的反码的基础上,加上符号位1了,最后结果还是11110111.与上面的结果是一样的。
补码:
正数的补码是它本身,负数的补码是它的反码加1,例如-8的补码是11111000.
例子来自百度百科,我自己重新演算了一遍。
(1) 已知原码,求补码。
例:已知某数X的原码为10110100B,试求X的补码和反码。
反码:绝对值原码,按位取反,得11001011
补码:反码+1,得11001100
(2) 已知补码,求原码。
分析:按照求负数补码的逆过程,数值部分应是最低位减1,然后取反。但是对二进制数来说,先减1后取反和先取反后加1得到的结果是一样的,故仍可采用取反加1 有方法。
例:已知某数X的补码11101110B,试求其原码。
有两种方法:
一是先减1,再取反。
补码减1得 11101101 ,取反得 10010010
补码取反 10010001 ,加1得 10010010
为什么需要反码及补码:
其实用原码,就可以表示所有数,那么为什么还要反码以及补码呢?之所以有反码,是在硬件中实现减法不太方便,所以需要把减法转换成加法来实现,比如1-1就相当于1+(-1),比如1+(-1)本身等于0,如果按照原码来计算 那就是00000001+10000001最后的结果就是10000010,也就是-2了,如果负数是用反码表示的,那么就成了00000001(正1的原码,也是1的反码)+11111110=11111111,也就是(-0)了,但是因为计算机里面不存在正0以及负0之说,所以最后又提出了补码的概念,补码就是在反码的基础上加1,加了补码后,就成了00000001(正1的原码,也是1的补码)+11111111=100000000,最前面的一个1超出了范围,会被抛弃,最后结果就是0了。
原码,反码,补码的表示范围:
原码的表示范围 -128到127(10000000本身代表-0,但计算机中0没有正负之分,所以就代表-128,可以通过sbyte的MinValue属性得知)
反码的表示范围 -127到127
补码的表示范围 -128到127(10000000到11111111分别代表-128到-1)
0的原码,反码,补码:
0的原码 00000000 和10000000
0的反码 00000000和 11111111
0的补码 00000000
关于溢出:
两个正数相加,或者两个负数相加,它们的值有可能超过了8个字节能表示的范围,这个时候最高位就会溢出。
127+127=01111111+01111111=11111110=--126 两个正数相加不可能是负数
(次高位有进位,但是符号位却没有进位,这时候产生溢出)
-127+(-127)=10000001+10000001=1 00000010 两个负数相加不可能是正数
(次高位没有进位,但是符号位却有进位,符号位的进位被丢弃)