当前位置 博文首页 > weixin_30629977的博客:计算机中带符号的整数为何采用二进制的

    weixin_30629977的博客:计算机中带符号的整数为何采用二进制的

    作者:[db:作者] 时间:2021-09-20 13:55

                     计算机中带符号的整数为何采用二进制的补码进行存储?

      我们都知道在计算机内部数据的存储和运算都采用二进制,是因为计算机是由很多晶体管组成的,而晶体管只有2种状态,恰好可以用二进制的0和1表示,并且采用二进制可以使得计算机内部的运算规则简单,稳定性高。在计算机中存在实数和整数,而整数又分为无符号整数和有符号整数,无符号的整数表示很简单,直接采用其二进制形式表示即可,而对于有符号数的表示却成了问题,如何表示正负?如何去处理正负号?下面来具体说下其中的原因,在这之前先了解一下原码、反码和补码这几个概念。

    1.原码、反码和补码的概念

      在了解原码、反码和补码之前先说一下有符号数和无符号数。用过C语言的都知道在C语言中用signed和unsigned来标识一个数是否是有符号还是无符号类型的。对于一个8bit的二进制来说,若当做无符号数处理,其能表示的整型值范围是0~255,但是这样表示数据就有个局限性,如果数据是负的该如何表示?因此就引入了有符号类型的概念,对于有符号类型,规定取最高位为符号位,若最高位为0,则为正数,否则为负数,这样一来对于8位二进制,示数值的就只有7位了,能够表示的非负数值范围变为0~127,负值范围为-127~-1,相当于可以理解为将无符号类型能够表示的128~255拿来去表示-127~-1了。事实上,在计算机内部存储中,计算机自己是无法去区分无符号还是有符号类型的,对于255和-1,在计算机内部存储的都是11111111。换个角度来说,如果事先知道内存中存储了这样一个8位二进制11111111,但是谁也不能肯定它具体表示什么数值,是-1还是255?这个是需要靠程序员自己去指定的,如果指定为无符号类型,则编译器则通过相应指令将其转换为数值255。事实上对于-x的二进制补码表示形式和(256-x)(256-x当做无符号类型处理)的二进制表示形式相同,从这里可以略微了解了补码的含义了。在教材中对于原码、反码以及补码一般是这么定义的:

      对于正数原码、反码以及补码是其本身。负数的原码是其本身,反码是对原码除符号位之外的各位取反,补码则是反码加1。

      因为(-x)的二进制补码形式和256-x的二进制表示形式相同,而255-x相当于对x的每一位取反,那么256-x就是255-x后加1。

      注意:1)原码、反码、补码的概念是针对有符号类型而言的。

         2)实数始终是有符号类型的(实数并不是采用补码形式存储的,具体可参考《浅谈C/C++的浮点数在内存中的存储方式》一文),整型数据包括无符号和有符号类型的。

    2.采用补码表示带符号的整数的原因

      对于有符号类型的整数,有原码、反码和补码三种形式,最后选择了补码来表示,具体来说有下面几点原因。

      1)能够统一+0和-0的表示

      采用原码表示,+0的二进制表示形式为0 000 0000,而-0的二进制表示形式为1 000 0000;

      采用反码表示,+0的二进制表示形式为0 000 0000,而-0的二进制表示形式为1 111 1111;

      采用补码表示,+0的二进制表示形式为0 000 0000,而-0的二进制表示形式为1 111 1111+1=1 0000 0000,因为计算机会进行截断,只取低8位,所以-0的补码表示形式为0000 0000。

      从上面可以看出只有用补码表示,+0和-0的表示形式才一致。正因为如此,所以补码的表示范围比原码和反码表示的范围都要大,用补码能够表示的范围为-128~127,0~127分别用00000000~01111111来表示,而-127~-1则用10000001~11111111来表示,多出的10000000则用来表示-128。因此对于任何一个n位的二进制,假若表示带符号的整数,其表示范围为-2^(n-1)~2^(n-1)-1,且有MAX+1=MIN。看下面一段代码:

    char ch=127;
    ch++;
    cs
    下一篇:没有了