二进制数的编码表示

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二进制数的编码表示相关的知识,希望对你有一定的参考价值。

数值信息在计算机内是采用二进制编码表示。数有正负之分,一般情况下,用"0"表示正号,"1"表示负号,符号位放在数的最高位。
例如,8位二进制数A = (+1011011),B = (-1011011),它们在机器中可以表示为:
A:01011011
B:11011011

计算机中几种常用的编码----原码、反码和补码。

1.原码
将符号位数字化为0或1,数的绝对值与符号一起编码,即所谓"符号-绝对值表示"的编码,称为原码。
例如:
整数:
X = +1011011,原码:[X]原 = 01011011;
X = -1011011,原码:[X]原= 11011011;
小数:
对于一个带符号的纯小数,它的原码表示就是把小数点左边一位用作符号位。
X = 0.1011,原码:[X]原 = 0.1011;
X = -0.1011,原码:[X]原 = 1.1011;

            当采用原码表示法时,编码简单直观,与真值转换方便。但原码也存在一些问题,一是零的表示不唯一,因为:[+0] = 000···0,[-0] = 100···0  零有二义性,
            给机器判零带来麻烦。二是用原码进行四则运算时,符号位需要单独处理,且运算规则复杂。例如加法运算,若两数同号,两数相加,结果取共同的符号;
            若两数异号,则要大数减去小数,结果冠以大号的符号。此外,借位操作如果用计算机硬件来实现是很困难的。

2.反码
反码很少使用,但作为一种编码方式和求补码的中间码,我们还是要学习一下的。
正数的反码与原码表示相同。
负数反码的符号位与原码相同(仍用1表示),其余各位取反(0变1,1变0)。例如:
X = +1100110, [X]原 = 01100110,[X]反 = +1100110;
X = -1100110,[X]原 = 11100110,[X]反 = 10011001;
X = +0000000,[X]原 = 00000000,[X]反 = 00000000;
X = -0000000,[X]原 = 10000000,[X]反 = 111111111;
和原码一样,反码中的零的表示也不唯一。
当X为纯小数时,反码的表示如下:
X = 0.1011,[X]原 = 0.1011,[X]反 = 0.1011;
X = -0.1011,[X]原 = 1.1011,[X]反 = 1.0100;

3.补码
(1)模数的概念
模数从物理意义上讲,是某种计量器的容量。例如,我们日常生活中用到的钟表,模数就是12。钟表计时的方式就是达到12就从零开始(扔掉一个12),这在数学上是一种"取模(或取余)运算(mod)"。例如:14%12 = 2。
如果现在的准确时间是6点整,而你的手表指向8点,怎样把表拨准呢?可以有两种方法:把表往后拨2小时,或把表往前拨10小时,效果是一样的。即:
8-2 = 6
(8+10)%12 = 6

         在模数系统中,8-2 = 8+10 (mod 12)
         上式之所以成立,是因为2与10对模数12是互为补数的(2+10 = 12)。因此,可以认可这样一个结论:在模数系统中,一个数减去另一个数,或者一个数加上一个负数,等于第一个数加上第二个数的补数:
                                                                                                                                                 8+(-2) = 8+10 (mod 12)
            我们称10为-2在模12下的"补码"。负数采用补码表示后,可以使加减法统一为加法运算。
            在计算机中,机器表示数据的字长是固定的。对于n位数来说,模数的大小是:n位数全为1,且末位再加1。实际上模数的值已经超过了机器所能表示的数的范围,因此模数在机器中是表示不出来的。若运算结果大于模数,则模数自动丢掉,也就等于实现了取模运算。
            如果有n位整数(包括一位符号位),则它的模数为2^n;如果有n位小数,小数点前一位为符号位,则它的模数为2。

    ***(2)补码表示法***
    由以上讨论得知,对于一个二进制负数,可用其模数与真值做加法(模减去该数的绝对值)求得其补码。
    例:  X = -0110    [X]补 = 2^4 + (-0110) = 1010
             X = -0.1011  [X]补 = 2 + (-0.1011) = 1.0101
                     由于机器中不存在数的真值形式,用上述公式求补码在机器中不易实现,但从上式可推导出一个简便方法。
                     "对于一个负数,其补码由该数反码的最末位加1求得。"
                    "对于正数来说,其原码、反码、补码形式相同。”

                    补码的特点之一就是零的表示唯一。
                      [+0]补 = 0 0 ···0           [-0]补 = 1 1 ··· 1 + 1 = 1 0 0 ··· 0
                                      |_____|                        |______|          |  |______|
                                                       n位                               n位              |      n位
                                                                                               |_ _ _ _ _ _ _ 自动丢失 
                    这种简便的求补码方法经常被简称为"求反加1"。

(3)补码的运算规则
采用补码表示的另一个好处就是当数值信息参与算术运算时,采用补码方式是最方便的。首先,"符号位可作为数值参加运算,"最后仍可得到正确的结果符号,符号无需单独处理;其次,采用补码进行运算时,减法运算可转换为加法运算,简化了硬件中的运算电路。
例如:
计算67-10=?
[+67]原 = 01000011, [+67]补 = [+67]原
[-10]原 = 10001010, [-10]补 = 11110110

                  0 1 0 0 0 0 1 1        [+67]补
            +  1 1 1 1 0 1 1 0        [-10]补
            ——————————————
             1 0 0 1 1 1 0 0 1   = 57
              |____________________________ 最高位的进位自然丢失
                 由于字长只有8位,因此加法最高位的进位自然丢失,达到了取模效果(即丢掉了一个模数)。
                 应当指出,"补码运算的结果仍为补码。" 上例中,从结果符号位得知,结果为正,所以补码即原码,转换成十进制数为57。
       如果结果为负,则是负数的补码形式,若要变成原码,需要对补码再求补,即可还原为原码。
 例如:
         10 - 67 = ?
                 [+10]原 = 00001010 = [+10]补
                 [-67]原 = 11000011     [-67]补 = 10111101

                        0 0 0 0 1 0 1 0
                +  1 0 1 1 1 1 0 1
                ——————————
                      1 1 0 0 0 1 1 1

                            [结果]补 = 11000111,[结果]原 = 10111001
                            所以结果的真值为-0111001,十进制为-57。

                    以上两个例子是否就可以说明补码运算的结果总是正确的呢?请看下面的例子:
例如:
        85 + 44 = ?
                      0 1 0 1 0 1 0 1
                    +  0 0 1 0 1 1 0 0
                ———————————
                          1 0 0 0 0 0 0 1
                    从结果的符号位可以看出,结果是一负数。但两个整数相加不可能是负数,问题出在什么地方呢?原来这是由于"溢出"造成的,即结果超出了一定位数的二进制数所能表示的数的范围。

            以上内容节选自清华大学出版社《C++语言程序设计(第4版)》

以上是关于二进制数的编码表示的主要内容,如果未能解决你的问题,请参考以下文章

编码

计算机编码

原码补码反码和移码

信息编码与数据表示

华为OD机试真题Java实现整数编码真题+解题思路+代码(2022&2023)

请用Python语言编程实现由十进制数到二进制数的转换。