• 编码:隐匿在计算机软硬件背后的语言(5)--负数的表示


    上一篇编码:隐匿在计算机软硬件背后的语言(4)--二进制减法器中,我们在减法器中对于减数大于被减数的情况当作溢出处理,实际上是由于加法器无法表示负数(至少在本文之前),本文的主题就是讨论负数的表示。

    同样先对十进制进行分析(易于理解),然后过渡到二进制。

    我们知道数字是没有界限的,然而我们所用到的数字都是有限的。所以先以三位十进制数为例。三位十进制数的范围为000-999,我们用这一千个数来表示-500~499。我们打算不用负号来表示负数,因为计算机里所有的信息都是用二进制来表示的,包括负号“-”。下面是我们的方法,以0为中心:


    也就是说以5、6、7、8、9开头的数字都是负数,这样

    -500,-499,-498,...,-1,0,1,...,498,499

    就可以表示为

    500,501,502,503,...,999,0,1,2,...,498,499

    可以注意到这形成了一个循环序列,最小的负数500看上去像最大整数499的延续。

    我们也可以这么理解,十进制有符号三位数可以表示为500,501,502,503,...,999,0,1,2,...,498,499。当然无符号三位数还是原来的000~999。

    上面的这种标记法称为10的补数,如果看了上一篇就会知道,我们在实现减法器的时候用到了对9的补数,实际上对10的补数结果等于对9的补数加1。例如-255对10的补数为(999-255+1)=745。

    有了10的补数,我们将不会再有减法。例如143-78=?计算机就会这么处理(假设计算机是十进制的),-78的补数是(999-078+1)=922,143-78=143+922=1065,由于是三位数,(最高位忽略)得到65。而65-150=65+850(150对10的补数)=915,实际上这就是-85。


    下面我们看看二进制。同样的在二进制中,我们需要求减数对2的补数。以有符号的8位二进制为例,0000 0000~1111 1111(十进制中0~255)以0为中心可以得到以1开头的数字都是负数,如下图所示


    也就是最高位成了符号位(有符号十进制中,最高位也是符号位,不过符号位数字为5、6、7、8、9)。

    二进制中为了计算2的补数,先计算1的补数然后加1。二进制中可以简化为取反然后加1。

    这样我们不用负号就可以表示负数。

    例如-127+124=1000 0001 + 0111 1100(124对2的补数)=1111 1101,实际上这就是-3。

    需要注意的地方就是,这里涉及到上溢和下溢的问题,例如125+125=1000 0011+1000 0011=1111 1010,以1开头,是负数-6,两个整数相加成了一个负数;同样的情况对负数也一样,-125+(-125)=1000 0011+1000 0011=1 0000 0110 由于是8位,这个数字是+6,两个负数相加成了一个整数。

    这样的加法是无效的。此时我们需要更多的位数来表示这些数字。


    从上面可以看出,三位无符号十进制数的范围为000~999,三位有符号十进制数(姑且这么说)的范围为-500~499。同样,

    8位无符号二进制数范围为0000 0000~1111 1111(0~255),8为有符号二进制数的范围为1000 0000~0111 1111(-128~+127)。

    所以我们必须弄清楚是有符号数还是无符号数,这也是二进制的麻烦之处。



    上一篇-->编码:隐匿在计算机软硬件背后的语言(4)--二进制减法器

  • 相关阅读:
    calcite介绍
    kylin介绍
    hbase(三)coprocessor
    流式计算-窗口
    实验室服务器琐事
    流畅的python笔记
    语义分割相关网络简述
    leetcode 696
    树的非递归遍历
    leetcode 665
  • 原文地址:https://www.cnblogs.com/hitfredrick/p/6403009.html
Copyright © 2020-2023  润新知