原码、反码、补码概念及转换

本文深入解析计算机中数据的存储方式,重点介绍补码的概念及其在正负数运算中的应用,通过实例对比原码、反码和补码,阐述补码如何简化计算机运算过程。

基础概念

  • 数据在计算机内部是以补码的形式存储
  • 数据分为有符号数和无符号数
    • 无符号数为正数,有符号数为负数,计算机内部是以补码的形式存储的
    • 正数的首位地址为0,其原码是由十进制数转换为二进制数
    • 负数的首位地址为1,其原码是由十进制数转换为二进制数,然后将首位地址改为1
  • 对于一个数,计算机要使用一定的编码方式进行存储,原码、反码、补码是机器存储一个具体数字的编码方式,原码、反码、补码是计算机原理的术语。说白了就是为了理解计算机使用二进制进行运算的原理。对于C/C++来说,是和数据类型有关的
原码

原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值

正数: 10 的原码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的原码 --> 1000 0000 0000 0000 0000 0000 0000 1010

注意: 二进制位的首位标识该二进制数是一个正数还是负数,正数为0,负数为1

反码
  • 正数的反码 == 原码
  • 负数的反码是在其原码的基础上,符号位(首位)不变,其余各个位取反
正数: 10 的原码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的原码 --> 1000 0000 0000 0000 0000 0000 0000 1010

正数: 10 的反码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的反码 --> 1111 1111 1111 1111 1111 1111 1111 0101
补码
  • 正数的补码 == 原码
  • 负数的补码是在其反码的基础上加1
正数: 10 的原码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的原码 --> 1000 0000 0000 0000 0000 0000 0000 1010

正数: 10 的反码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的反码 --> 1111 1111 1111 1111 1111 1111 1111 0101

正数: 10 的补码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的补码 --> 1111 1111 1111 1111 1111 1111 1111 0110

三种编码方式存在的原因

计算机只会做加法计算

当两个正数之间使用原码进行运算就可以解决

// 由于计算机只会做加法运算,减法运算在计算机的表现形式为
10 + 1

使用原码进行计算如下:
10 转成原码 --> 0000 0000 0000 0000 0000 0000 0000 1010
1  转成原码 --> 0000 0000 0000 0000 0000 0000 0000 0001
两者相加    --> 0000 0000 0000 0000 0000 0000 0000 1011			// 该原码转成十进制为 11

当正数和负数使用原码运算的时候就会出现问题

// 由于计算机只会做加法运算,减法运算在计算机的表现形式为
10 - 1 == 10 + (-1)      // 后者为计算机的表现形式

使用原码进行计算如下:
10 转成原码 --> 0000 0000 0000 0000 0000 0000 0000 1010
-1 转成原码 --> 1000 0000 0000 0000 0000 0000 0000 0001
两张相加    --> 1000 0000 0000 0000 0000 0000 0000 1011			// 该原码转成十进制为 -11

因为正数和负数之间使用原码运算会出现问题,为了解决这个问题,反码就出现了

// 使用反码进行计算
10 - 1 == 10 + (-1)      // 后者为计算机的表现形式

使用原码进行计算如下:
10 转成原码 --> 0000 0000 0000 0000 0000 0000 0000 1010 --> 转成反码 --> 0000 0000 0000 0000 0000 0000 0000 1010
-1 转成原码 --> 1000 0000 0000 0000 0000 0000 0000 0001 --> 转成反码 --> 1111 1111 1111 1111 1111 1111 1111 1110
10 转成反码   --> 0000 0000 0000 0000 0000 0000 0000 1010
-1 转成反码   --> 1111 1111 1111 1111 1111 1111 1111 1110
两者反码相加 --> 1 0000 0000 0000 0000 0000 0000 0000 1000	// 左侧超出的部分会被自动去掉,该原码转成十进制为 8

注意:反码在进行正数与负数之间的运算所得的值会相差1

由于反码在进行正数与负数之间的运算所得的值会相差1,为了解决这个问题,补码就出现了

10 转成补码   --> 0000 0000 0000 0000 0000 0000 0000 1010
-1 转成补码   --> 1111 1111 1111 1111 1111 1111 1111 1111
两者补码相加 --> 1 0000 0000 0000 0000 0000 0000 0000 1001	// 左侧超出的部分会被自动去掉,该原码转成十进制为 9
### 原码反码补码的基本概念与区别 在计算机系统中,数值的表示运算通常采用**原码反码补码**三种编码方式,它们主要用于处理有符号整数。这三种编码方式在表示正数、零以及进行加减运算时存在差异。 #### 原码 原码是一种最直观的表示方式,其最高位为符号位(0表示正数,1表示数),其余位表示数值部分。例如,+5的原码为`0000 0101`,-5的原码为`1000 0101`(以8位为例)。 原码的缺点是存在**两个零**(+0-0),分别为`0000 0000``1000 0000`。此外,原码的加减法运算需要额外的判断逻辑,不能直接进行符号位参与的运算[^3]。 #### 反码 反码是对原码的一种改进,其符号位与原码相同,数值位则根据原码进行变换。对于正数,反码原码相同;对于数,数值位需要**逐位取反**。 例如,-5的反码为`1111 1010`(原码为`1000 0101`,取反后得到)。反码同样存在**两个零**,分别为`0000 0000``1111 1111`。 反码的加减运算相比原码更简单,**符号位可以直接参与运算**。加法时,直接将反码相加,并采用**循环进位**(即最高位进位加到最低位);减法时,只需将被减数的反码加上减数数的反码即可,同样需要循环进位[^1]。 #### 补码 补码是现代计算机中广泛使用的编码方式,它解决了原码反码中存在的多个问题,如两个零的存在运算复杂性。 正数的补码原码反码相同;数的补码反码加1得到。例如,-5的补码为`1111 1011`(反码为`1111 1010`,加1后得到)。 补码的最大优点是**只有一个零**(`0000 0000`),并且其加减运算无需循环进位,**可以直接进行模运算**。例如,`-1 + 1`的结果为`0000 0000`,而不会出现额外的进位处理[^1]。 ### 原码反码补码之间的转换规则 #### 原码反码 - 正数:反码原码相同。 - 数:符号位不变,数值位逐位取反。 #### 反码补码 - 正数:补码反码相同。 - 数:反码加1得到补码。 #### 补码反码 - 正数:反码补码相同。 - 数:补码减1得到反码。 #### 反码原码 - 正数:原码反码相同。 - 数:符号位不变,数值位再次逐位取反。 #### 补码原码 - 正数:原码补码相同。 - 数:先将补码减1得到反码,再将反码取反得到原码。 ### 补码的优势与应用 现代计算机普遍采用补码表示数值,其优势主要体现在以下方面: - **只有一个零**:避免了原码反码中存在两个零的问题。 - **简化加减运算**:补码可以直接进行加减运算,无需额外的进位处理或符号判断。 - **模运算特性**:补码支持模运算,使得溢出处理更加自然。 例如,在8位补码系统中,-128的表示为`1000 0000`,而+127的表示为`0111 1111`。补码的表示范围为**-128~127**,比原码反码多了一个最小值[^3]。 ### 示例代码:补码加法运算 ```cpp #include <iostream> int main() { int a = -5; int b = 3; int result = a + b; std::cout << "Result: " << result << std::endl; return 0; } ``` 在上述代码中,变量 `a` `b` 的值分别以补码形式存储在内存中,加法运算直接使用补码进行,无需额外处理符号位。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值