有符号数无符号数补码反码

image-20220119165839638

有符号数和无符号数

在计算机中,使用0表示正数,使用1表示负数,比如237的二进制为011101101,而-237的二进制为111101101,约定符号位为数字位的最前面。比如用两个字节来存正整数237

1
2
3
237 = 0000 0000 1110 1101
|
符号位

如果用两个字节在存负整数-237则表示为:

1
2
3
-237 = 1000 0000 1110 1101
|
符号位

这种对于正数和负数的表示方法称为**原码表示法**

二进制原码表示法

使用0表示正数、1表示负数,规定符号位位于数值第一位,原码表示法虽然有利于理解,但是对于一些特殊情况还是有一定的缺陷的,比如0使用原码表示法有两种表示方式:

1
2
+0 = 00
-0 = 10

但是不管+0还是-0都为0,并且使用原码进行运算非常复杂,特别是两个操作数符号不相同的时候,需要判断两个操作数的绝对值大小,并且使用绝对值大的数减去绝对值小的数,并且对于符号值,需要以绝对值大的符号为准

二进制补码表示法

为了解决原码运算复杂等问题,希望找到使用正数代替负数的方法,使用加法代替减法操作,从而消除减法,提出了补码表示法,一个数的补码可以分为两种情况,假设一个数为x

  1. x >= 0x的补码就为x
  2. x < 0x的补码为2^n+1 + x其中n表示x的位数
    例如x = 13,则x的原码以及补码为:
    1
    2
    3
    4
    5
    6
    7
    原码:x = 13 = 0 1101
    |
    符号位

    补码:x = 13 = 0 1101
    |
    符号位
    如果x = -13,则x的原码以及补码为:
    1
    2
    3
    4
    5
    原码:x = -13 = 1 1101
    |
    符号位

    补码:x = -13 = 2^4+1 + (-13) = 32 - 13 = 100000 - 1101 = 10011
    这里再举一个例子用来熟悉怎么计算原码和补码:
    1
    2
    3
    4
    5
    6
    7
    x=-7
    原码:x = -7 = 1 0111
    |
    符号位
    补码:x = -7 = 2^4+1 + (-7) = 100000 - 0111 = 1 1001
    |
    符号位

    正数的补码 = 原码, 负数的补码 = {原码符号位不变} + {数值位按位取反后+1}

二进制反码表示法

补码虽然消除了负数,但是计算补码的过程中。还是使用了减法,为了找出原码和补码之间的规律消除转换过程中的减法,提出了反码表示法,一个数的反码同样可以分为两种情况,假设一个数为x

  1. x >= 0时,反码就为x
  2. x < 0时,反码为(2^n+1 - 1) + x其中n表示x的位数

例如x = 13,则x的原码、补码以及反码分别为:

1
2
3
4
5
6
7
8
9
原码:x = 13 = 0 1101
|
符号位
补码:x = 13 = 0 1101
|
符号位
反码:x = 13 = 0 1101
|
符号位

如果x = -13,则x的原码、补码以及反码分别为:

1
2
3
4
5
6
7
8
9
原码:x = -13 = 1 1101
|
符号位
补码:x = -13 = 2^4+1 + (-13) = 32 - 13 = 100000 - 1101 = 1 0011
|
符号位
反码:x = -13 = (2^4+1 -1) + (-13) = 31 - 13 = 11111 - 1101 = 1 0010
|
符号位

同样再举一个例子用来熟悉怎么计算原码、补码和反码:

1
2
3
4
5
6
7
8
9
10
x = -7
原码: x = -7 = 1 0111
|
符号位
补码: x = -7 = 1 1001 (原码符号位不动,其余位取反后再加1)
|
符号位
反码:x = -7 = (2^4+1 - 1) + (-7) = 31 - 7 = 11111 - 0111 = 1 1000
|
符号位

总结

手算完上面的几个例子后,相信对于原码、补码、反码的计算应该很熟悉了,我们再把几个例子汇总一下,总结一下规律:

十进制 原码 补码 反码
13 0 1101 0 1101 0 1101
-13 1 1101 1 0011 1 0010
7 0 0111 0 0111 0 0111
-7 1 0111 1 1001 1 1000

仔细观察,可以总结出以下规律:

  1. 负数的补码等于原码(除了符号位)按位取反再加1
  2. 负数的反码等于原码(除了符号位外)按位取反
  3. 负数的补码等于反码加1

通过总结出的规律,相信可以很快速的计算出一个数的反码和补码了