计算机中的数值表示,二进制,原码反码补码

  1. 在cpu 底层中,用高低电平表示1和0,通过逻辑门的组合可以 存储修改读取 该组合 电平状态即1和0,此为存储单元。
  2. 如何用1和0表示更多的数据信息,这就是二进制,引入位数表示更大的数字。
  3. 但是位数是有限的,而且不能尽量不能随意浪费。
  4. 计算机可以可以利用 异或门 和 与门 进行一位加法运算(半加器,全加器)
    1. 通过级联全加器实现多位加法,但延迟较高 行波进位加法器
      1. (延迟较高应该是电路更长,虽然逻辑简单,但是没有优化。通电进行一次)
      2. 因为电流也需要时间,完成一次加法,必须等电流通过所有电路, 这个时间应该就是时钟
    2. 通过并行计算进位优化性能,但硬件更复杂 超前进位加法器
      1. (硬件复杂应该是指逻辑复杂,需要更过不同的逻辑,及相应不同的硬件实现)
  5. 如何实现减法
  6. 原码、补码、反码
    1. 计算机中用到减法,会用一位最高位表示正负号,其他位表示数值。
    2. 但是要透过概念看本质,首先原码、反码、补码的概念顺序要反过来,我们不是根据原码、反码进行运算,计算机中运算只用到补码!这个顺序很重要。
    3. 本质的运算是模运算和溢出的概念
      1. 一个4位二进制,它的模数是2^4 = 16, 但是我们用它表示的数字是-7~7。这是我们定的概念。

      2. 补码的设计基于模运算。对于一个 n 位的二进制系统,模数是 2^(n)。补码的本质是:

        • 一个负数 −B的补码实际上是 2^n - B。

        • 因此,A−B可以表示为 A + 2^n - B = 2^n + (A - B)

          由于计算机的位数是固定的,超出 n 位的部分会被丢弃(溢出),所以结果就是 A−B,如果结果没有超出,结果也是正确的。

        1. 因为没有超出的话,说明结果A-B的结果为负数, 这个时候结果仍然是补码,也是正确的(计算机运算中不存在反码原码!反码原码只是为了容易理解)。
      3. 例子

        4 = 2^4 = 16   3位数值表示(-8^8) + 1位符号位
        6-2 = 4
        6+(-2) 
        原码:0110(6)  1010(10)  
        反码:0110(6)  1101(13)  
        补码:0110(6)  1110(14)  10100(20)   20 -16=4
        
        6-7 = -1
        6+(-7)
        原码:0110(6)  1111(15)  
        反码:0110(6)  1000(8)  
        补码:0110(6)  1001(9)  1111(15)  =4
        
        6-7+2
        1111 + 0010(2) = 10001 = 1
        
        
        其实计算机中只有补码,用补码进行运算!
        这里可以看到,我们其实是用14 表示 -2 用9 表示-7, 用15表示-1
        
        
  7. 计算中小数的表示,进制问题
    1. 不同进制的真值其实是每一位的数值剩余该位权重 累加,记住10进制 也只是一种进制表示方法而已,明白数量的真实含义

      二进制
      1 111
      1*2^3 + 1*2^2 + 1*2^1 + 1*2^0 = 15
      为什么要1*2^3 因为在这个数之前已经有1*2^3 - 1 个数 即从000-111(0-7)  这个位置的权重就为2^3(8)
      
      十进制
      1 111
      1*10^3 + 1*10^2 + 1*10^1 + 1*10^0
      
      十六进制
      1 111
      1*16^3 + 1*16^2 + 1*16^1 + 1*16^0
      
    2. 整数十进制转二进制

      1. 模二除法
        1111(10)
        1111/2=555   1
        555/2 =277   1
        277/2 =138   1
        138/2 =69    0
        69/2  =34    1
        34/2  =17    0
        17/2  =8	 1
        8/2   =4	 0
        4/2   =2	 0
        2/2   =1	 0
        1/2   =0     1
        直到商为0
        
        结果为余数倒数排列100 0101 0111 为什么?
        按除以2 的次数,得到每位上的结果
        验证
        1*2^10 + 1*2^6 + 1*2^4 + 1*2^2 + 1*2^1 + 1*2^0
        = 1024 + 64 + 16 + 4 + 2 + 1
        = 1111
        
        
      2. 小数使用 乘二取整
        小数点每一位的权重是2^(-n)
        0.1(2) = 0.5(10)
        0.01(2) = 0.25(10)
        0.001(2) = 0.125(10)
        0.001(2) = 0.0625(10)
        
        0.611(10)
        0.611*2 = 1.222  取 1
        0.222*2 = 0.444  取 0
        0.444*2 = 0.888  取 0
        0.888*2 = 1.776  取 1
        0.776*2 = 1.552  取 1
        0.552*2 = 1.104  取 1
        0.104*2 = 0.208  取 0
        0.208*2 = 0.416  取 0
        ...
        结果:0.10011100...     因为二进制小数每位的权重可以预料到会有精度问题,而且很多数对于二进制来说就是无理数或者无限循环小数(十进制特殊处?为何十进制为主流)
        并且n 位十进制 转成二进制 通常位数有 5^n 位以上(除非正好是2的-n 相加的结果),结果才较准确
        
        验算结果
        1*2^(-1) + 1*2^(-4) + 1*2^(-5) + 1*2^(-6) = 
        0.5 + 0.0625 + 0.03125 + 0.015625 = 0.609375
        
        其他例子
        0.1(10) = 0.000110011 (第二位开始 0011 循环)
        
        
        
        乘2 也可以看成是 除以0.5 它其实是为了确定每一位二进制位上的系数是1 还是 0(这是一种方法去确定每位的系数,你也可以用更复杂的基准,不为1,甚至是从右特定位往左计算)
        为什么不和整数一样除以2,是因为我们要转的数是小数,所有的小数都没有2,小数乘二取整基准是第一位小数位2^-1, 我们确定的方向是从左到右,通过是否大于1判断系数,而整数位我们基准是2,从右往左,通过余数确定 每位系数。
        而且说到底,这只是一种方法,我们能用这种方法简便的去确定每位的系数。
        
        
posted @   jmwyc  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示