负数在计算机中的编码形式

  • 整理了下关于原码、反码、补码的相关内容,以及负数的表示和加法运算。

  • 原码、反码和补码:

    • 原码:机器码,原本的表示法
    • 反码:除符号位(最高位)外取反
    • 补码:反码加1,正数的补码反码都是原码本身
    • 手动求补码:先写出该负数的相反数(正数),再将该正数的二进制写出来,对二进制取反,最后加1。
  • 二进制:计算机底层的存储都是以二进制形式存储,最小单位为bit,存放一位二进制,0或1,计算机处理数据最基本单位是字节(Byte,简称B),8个二进制位为1个字节,即:1B = 8bit。

    • java 基本数据类型对应的存储空间:

      数据类型存储空间bit数取值范围
      boolean1字节1 * 8true(0000 0001),false(0000 0000)
      byte1字节1 * 8在这里插入图片描述
      char2字节2 * 8在这里插入图片描述
      short2字节2 * 8在这里插入图片描述
      int4字节4 * 8在这里插入图片描述
      long8字节8 * 8在这里插入图片描述
      float4字节4 * 8
      double8字节8 * 8
    • 数据类型所允许的最大值:与二进制位数有关,一个字节所允许的最小值为:0000 0000,最大值为:1111 1111,即在这里插入图片描述
      所以一个n位的二进制允许的最大值的计算方式:在这里插入图片描述

  • 有符号数和无符号数:在计算机中,需要区分正负的数据类型,称为有符号数据类型,例如int,包含正数也包含负数;不需要区分正负的数据类型,称为无符号数据类型。

    • 无符号类型:以单字节数为例,如果指定一个数据类型为无符号类型,那么最高位也就是最左边的一位,代表的意义和其他位相同,表示数的大小:无符号二进制1000 0000 --> 十进制 128。它的取值范围:0 ~ 255
    • 有符号类型:以单字节数为例,指定一个数据类型为有符号类型,那么最高位称为符号位,不再代表数字大小,作为正负数的标志,如果符号位是1,代表负数,如果是0,代表正数。单字节数的取值范围:-128 ~ 127,表示的数字个数不变,范围改变。
    • 负数:由于在负数中,-1是最大的负整数,所以在用二进制表示时,无论是几个字节数,都使用全1来表示 -1: 1111 1111。-1-1=-2: 1111 1110,依次减下去可以获取单字节的最小负值,-128: 1000 0000。
      • 使用反码和补码的意义:原码是由十进制转为二进制所得,反码是由原码除符号位依次取反所得,补码是在反码基础上+1。
        • 对于正数三种编码相同:在这里插入图片描述

        • 对于负数则不同:在这里插入图片描述
          首先,负数的原码是由正数1加负号,也就是符号位改为1得到,之所以这样设计是为了让符号位也参与计算,使得减法也能用加法表示,毕竟减去一个数等于加上一个负数,在这里插入图片描述
          简化基本运算器的设计。

          • 原码的计算方式:在这里插入图片描述
            很明显以原码来计算是不正确的。为了解决这种问题,引入了反码。
          • 反码的计算方式:在这里插入图片描述
            由结果可见,计算结果数值是对的,但是这就导致了另外一个问题,0这个数字带符号是没有意义的,现在就变成了一个 +0编码和一个 -0编码,针对这两个编码表示0的问题,引入了补码。
          • 补码的计算方式:在这里插入图片描述
            这样计算结果是正确的,也不会出现正负0的情况,那么对于 1000 0000可以用来表示 -128,补码的出现既解决了正负0问题,也使得表示的负数多了一位。所以一个字节有符号数用补码表示的取值范围为 -128 ~ 127,用反码或原码表示的取值范围为 -127 ~ 127。(由于 1000 0000是用-0的补码来表示-128,所以-128并没有原码和反码表示)
          • 在计算机内部都是使用补码来计算和存储。补码所依据的数学理论是同余,具体论证过程
  • 一个具体的Java例子:

    • 问题如下:
      int 类型数值128强转为byte类型,打印结果,输出为什么是-128?
    • 解释:
      • int类型128的原码:0000 0000 0000 0000 0000 0000 1000 0000,反码和补码相同
      • 当int被强转为byte类型时,由于byte只有1个字节,截断高24位,保留低8位:1000 0000
      • 在进行打印时,short、byte类型都会作为int类型计算,此时会进行有符号填充操作,前24位都填1,1111 1111 1111 1111 1111 1111 1000 0000
      • 对补码 -1 再取反结果为:1111 1111 1111 1111 1111 1111 0111 1111
      • 最终结果:1000 0000 0000 0000 0000 0000 1000 0000,由于除符号位以外,高位都是0,有效位为8位,128,加上标志位,结果是-128
    • 这个小问题涉及到了最基础的编码知识,还是值得探究一番。
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值