关于原码、反码、补码以及为什么存在原码、反码、补码

定义

原码

数字的二进制表示。在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余二进制位表示数值的大小。例如:10的一个比特位原码是00001010。

反码

在原码的基础上符号位不变,其余位分别取反(0变成1,1变成0)。

补码

在反码的基础上加一。

提醒

正数的原,反,补码都一样。最后储存在内存的就是所有数据的补码!!!

为什么存在(以下都以一个byte位来演视)

为什么存在反码

反码的运算时,符号位也参与运算。

一个比特位一打眼看过去所能表示的数值的范围是01111111(127)到11111111(-127)但是实际上可以表示的范围是127到-128。

对于正数的加减法来说有

图中的的1+2每一位对应相加得到00000011转换为十进制就是3。但是如果对于负数加负数的话就有问题了。

图中-2加-1正确答案应该是-3但是利用每个二进制位对应相加所得到的结果却是00000011(三的二进制位)

所以原码对于负数的加减就有问题了。

原本等于-3的结果却等于了3,经过多组数据来看所有的结果都相反,原本应该等于-5的结果却等于了5。

这样每个数都相反,所以以前的程序员就想着把二进制位也取反符号位不动看能不能解决问题。所以这样就产生了反码!

反码的产生是为了解决负数计算的问题。

下图就是利用反码来计算有关于负数的计算-2加1

1是正数所以反码和原码一样。

为什么存在补码

首先声明补码的引入是为了解决负数运算产生了跨0的情况。在反码的运算时符号位也参与运算。

先看示例

对于图中如果一个负数和一个整数相加跨过了0,就会有错误,图中的正确答案应该是2但是却得到了1的反码(因为1是正数,所以原码,反码,补码都一样)这是为什么呢?

原因就是在反码系统中11111111和00000000都表示0一个表示-0的反码一个表示+0的反码。

从-0到+0的过程还需要多加一所以得到的结果会比预期的少一

为了解决跨0的运算问题就引入了反码的概念。因为正数的原码,反码,补码都一样只有负数的补码需要在反码的基础上加一,所以就可以避开0有两种表达形式,让0只有00000000这一种表达形式。

这样-127的补码就从10000000变成了10000001,因为0的补码是00000000而1-127的补码是1000001这中间少了一个数10000000所以规定10000000就是-128(注意这个是规定即系统遇到100000000就认为它是-128不会有什么别的运算转换,-128没有原码和反码)。

所以一个比特位的取值范围就从127变成了-128了。

因为补码是一点一点从原码到反码最后到补码的所以它具有原码的解决正数运算的能力、和反码解决负数不跨0的计算能力、和补码本身解决跨0的情况。所以最后在内存中存储的就是补码了!!!

### 原码反码补码的概念及区别 #### 一、概念介绍 - **原码**是指最高位作为符号位(0代表正数,1代表负数),其余各位表示数值绝对值的二进制编码形式。对于8位机器而言,+3的原码为`0000 0011`,而−3则为`1000 0011`[^4]。 - **反码**用于表示带符号整数,在正数情况下其表现形式同原码一致;当处理负数时,则需将除符号位外的所有位取反操作得到的结果即为其反码。例如,按照上述例子中提到的数据,+3依旧保持不变仍为`0000 0011`,但是-3会变成`1111 1100`[^2]。 - **补码**同样适用于表达带有符号属性的整型变量。正值情形下它也跟前两者一样呈现出来;而对于负值来说,可以通过对其对应的反码加1获得最终结果。还是以上面那个实例为基础,那么此时-3应该被记录成`1111 1101`的形式。 #### 二、特性对比分析 | 编码方式 | 正数表示方法 | 负数表示方法 | |----------|---------------------|----------------------------------| | 原码 | 符号位为0 | 符号位为1 | | 反码 | 同于原码 | 非符号位按位取反 | | 补码 | 同于其他两种 | 对应反码基础上再加1 | 值得注意的是,在实际应用过程中,补码因为可以使得减法转换成加法执行从而简化硬件实现逻辑,并且解决了零存在两个不同表示的问题(-0 和 +0),所以在当今几乎所有的计算设备内部都采用了这种编码方案来进行数值存储与运算[^3]。 ```python def get_complement(num, bit_length=8): """获取给定十进制整数num在指定比特长度下的补码""" if num >= 0: return bin(num)[2:].zfill(bit_length) else: # 处理负数情况 positive_bin = bin(abs(num))[2:].zfill(bit_length) inverted_bits = ''.join(['1' if b=='0' else '0' for b in positive_bin]) complement = int(inverted_bits, 2) + 1 return format(complement % (1 << bit_length), f'0{bit_length}b') print(get_complement(3)) # 输出:00000011 print(get_complement(-3)) # 输出:11111101 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值