原码、反码和补码之间符号位改变的特殊情况分析(正零+0,负零-0,)

一、问题背景

博主在准备应聘的笔试、面试时,再次采用了多年以来的Java工具书《Java疯狂讲义》,当博主看到该书的《Java疯狂讲义》第3章(数据类型和运算符)时,里面涉及了原码、反码和补码之间符号位改变的特殊情况,因此博主想完全地探讨其全部的特殊情况。

二、原码、反码和补码

当用二进制来表示一个数时,最高位是符号位,符号位是0表明它是一个正数,符号位是1表明它是一个负数。

计算机都是通过正数、负数的补码来运算,而不是正数、负数的原码。

例如用8位二进制来表示-128~127的127时,-128 ~ 127的原码、反码和补码表格如下:
在这里插入图片描述

1.原码、反码和补码之间的运算规则

1.1正数的原码、反码和补码之间的运算规则

一个正数,按照绝对值大小转换成的二进制数就是正数的原码。
正数的原码与其反码和补码都相同。

例如用8位二进制来表示-128~127的127时(实际例子:Java的Byte类型),127的原码、反码和补码都是01111111

1.2负数的原码、反码和补码之间的运算规则

一个负数,按照绝对值大小转换成的二进制数,然后最高位补1,就是负数的原码。
负数的反码为对该负数的原码除符号位外各位取反。
负数的补码为对该负数的原码除符号位外各位取反,然后在最后一位加1。

补码的设计目的是:

  1. 使符号位能与有效值部分一起参加运算,从而简化运算规则。
  2. 使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计。

在这里插入图片描述上述图片的负数的原码、反码和补码之间的运算规则分别提到了反码最低位+1,+1时符号位可能进位,绝不借位补码最低位-1,-1时符号位不可能借位,绝不进位,它们的解释如下:

  1. 反码最低位+1,+1时符号位可能进位,绝不借位是指:特殊情况下的[-0]反码1111 1111在+1后因为符号位发生了进位,得到[-0]补码1 0000 0000。而反码最低位+1是加法操作,故绝不会有借位操作。
  2. 补码最低位-1,-1时符号位不可能借位,绝不进位是指:特殊情况下的[-128]补码1000 0000在-1反推其[-128]反码0111 1111时会出现符号位借位的情况。但是编程领域规定:在用8位二进制来表示-128~127的一个数时,-128仅有补码而没有对应的反码、原码,所以特殊情况下的[-128]补码反推其反码导致的符号位借位情况是不可能出现的。而补码最低位-1是减法操作,故绝不会有进位操作。

例如用8位二进制来表示-128~127中的-3时(实际例子:Java的Byte类型),首先将-3的绝对值+3转换成二进制数0000 0011,然后将其最高位+1,就得到-3的原码1000 0011-3的原码1000 0011在除符号位外其余位取反得-3的反码1111 1100-3的反码1111 1100在+1后得到-3的补码1111 1101

[+3]原码=0000 0011
[-3]原码=1000 0011
[-3]反码=1111 1100
[-3]补码=1111 1101

1.3正零(+0)和负零(-0)的原码、反码和补码

因为是正的,所以正零+0的原码与其反码和补码都相同;而因为是负的,负零(-0)的原码、反码和补码之间都不相同。

[+0]原码=0000 0000, [-0]原码=1000 0000
[+0]反码=0000 0000, [-0]反码=1111 1111
[+0]补码=0000 0000, [-0]补码=0000 0000

由上可见,+0和-0的补码是一样的。即0的补码只有一种表示。

这里解释一下[-0]补码是怎么得来的: [-0]原码1000 0000在除符号位外按位取反后得到[-0]反码1111 1111,[-0]反码1111 1111再+1后因为符号位发生了进位,得到[-0]补码1 0000 0000。 9位二进制的[-0]补码1 0000 0000已经超出了8位二进制的位数限制,那只能保留最低的8位二进制,即最高位1要被舍弃,因此最后[-0]补码还是0000 0000

因此+0和-0的补码是一样的,补码能表示的数的个数比原码、反码各少了一个,所以补码可以多表示一个真值为-128的数。

但是,多表示的这个数-128比较特殊,只有补码,没有原码和反码。

1.4特殊负数-128的原码、反码和补码

编程领域规定:在用8位二进制来表示-128~127的一个数时,-128仅有补码而没有对应的反码、原码。

1.5二进制符号位(最高位)改变的特殊情况

整个编程领域中,二进制符号位(最高位)改变的特殊情况主要为以下3种:
在这里插入图片描述

  1. 在负数原码与负数反码互相转换时的取反操作中,符号位不变。
  2. 负数反码+1得负数补码时,符号位可能进位。但负数补码-1得负数反码时,符号位不可能借位。

特殊情况下的[-0]反码1111 1111在+1后因为符号位发生了进位,得到[-0]补码1 0000 0000
特殊情况下的[-128]补码1000 0000在-1反推其[-128]反码0111 1111时会出现符号位借位的情况。但是编程领域规定[-128]仅有补码,[-128]是没有对应的反码、原码的,所以特殊情况下的[-128]补码反推其反码导致的符号位借位情况是不可能出现的。

  1. 位运算符的按位非~: 单目运算符,将操作数的每个位(包括符号位)全部取反。

如程序执行~-5的结果是4,其运算原理如下:
在这里插入图片描述

参考文献:
[1]关于 -128 ,+128,-0,+0,-1 的反码补码
[2]+0或者-0的源码、反码、补码
[3]8位原码反码补码表
[4]补码10000000为什么可以表示-128?
[5]为什么-0的补码是00000000?
[6]正数负数的原码、反码、补码
[7]终于搞懂你了——补码!

  • 24
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐李同学(李俊德-大连理工大学)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值