如何从根源上理解原码、反码、补码?

文章讲述了计算机中的原码、反码和补码技术,用于解决负数运算中的符号位问题和越位计算。通过反码和补码,可以确保负数运算的准确性,正数保持不变,数值计算时通常采用补码方式。

 1、原码:

因为计算机元件只能有2个状态,故利用0和1来表示数值,即二进制。计算机二级制数字中,最高位当作符号位,默认0为正数,1为负数,原码能够正常表达正数和负数,0则有+0和-0这两种状态
由于计算机没有减法,所以减法在运算时相当于加上负数,如【2-1】其实是【2+(-1)】,当负数参与运算时,由于符号位的存在,会导致基于源码的计算结果错误。

eg:【2-1】源码计算(4bit情况下)
0 010
1 001
-------
1 011
结果是-3,而实际应当是2-1=1才对

2、反码:

为了解决源码中负数运算错误的问题,引入反码概念。即针对负数,除符号位外,运算位进行0和1的互换,计算时如果发生越位,则在末尾+1。但是反码中仍存在+0和-0的情况,且计算式要额外资源处理越位的情况。 

eg:【2-1】反码计算(4bit情况下)
0 010
1 110
-------
0 001(其实是10000,但本处默认是4bit,左边1发生越位了,所以考虑越位情况,末尾+1,变成0001)
结果是1,结果正确。

3、补码

同样针对负数,为了解决反码中【+0和-0共存】和【计算越位的问题】,在反码基础上+1得到补码。
这时候-0的1000(反码)+1= 0 000,和+0相同了
补码时数值计算时的直接值。 

eg:【2-1】补码计算(4bit情况下)
0 010
1 111
-------
0 001(其实是10001,由于默认是4bit,左边1仍然越位,但不用再考虑越位情况了,结果不变) 
结果是1,结果正确,而且计算的时候不需要单独考虑越位的情况。

总结一下:

几种码均为负数参与计算而设计,需要对负数改造,正数保持不变。
数值计算时使用补码来参与计算。

### 原码反码补码的定义 #### 原码 原码是一种简单的二进制表示方法,在数值前增加一位符号位来区分正负数。对于一个 n 位二进制数,最高位作为符号位:0 表示正数,1 表示负数[^3]。 例如,8 位二进制下,`+5` 的原码为 `00000101`,而 `-5` 的原码为 `10000101`。 缺点在于,原码无法直接用于加减运算,尤其是涉及负数时会出错。例如,`1 + (-1)` 应该等于 `0`,但在原码中计算结果却是错误的[^3]。 --- #### 反码 反码是对原码的一种改进形式。其定义如下: - **正数**的反码与其原码相同。 - **负数**的反码是将其原码除符号位外的所有位按位取反。 例如,8 位二进制下,`+5` 的反码仍为 `00000101`,而 `-5` 的反码为 `11111010`(将 `10000101` 中的低 7 位取反得到)。 虽然反码解决了部分问题(如互为相反数相加得零),但它仍然存在问题,特别是在处理两个负数相加时容易出错[^3]。 --- #### 补码 补码进一步优化了反码的设计,广泛应用于现代计算机系统中的数值表示和运算。具体定义如下: - **正数和零**的补码与它们的原码一致。 - **负数**的补码通过以下方式获得:先求其反码,再对反码加 1[^3]。 例如,8 位二进制下,`+5` 的补码仍是 `00000101`,而 `-5` 的补码为 `11111011`(由 `-5` 的反码 `11111010` 加 1 得到)。 补码的优点在于它能有效解决加减法运算中的溢出问题,并支持统一使用加法器完成各种运算操作[^2]。 --- ### 原码反码补码的应用场景 #### CPU 和硬件层面 在计算机内部,所有的整数运算几乎都基于补码实现。这是因为补码可以简化硬件设计,使得加法器既能执行加法也能间接完成减法操作[^1]。例如,当需要计算 `A - B` 时,实际的操作被转化为 `A + (-B)`,其中 `-B` 是以补码形式存储的值。 #### 数据类型范围扩展 采用补码还可以扩大有符号整型的数据表示范围。例如,8 位二进制数用原码反码表示时,可覆盖区间为 `[-127, +127]`;但如果改用补码,则能够表示更广的范围 `[−128, +127]`。 #### 高级编程语言 尽管程序员通常接触的是原码形式的输入输出(如 C/C++ 或 Python 中显示的结果),但实际上这些数值会被自动转换成补码供处理器处理[^1]。因此,了解三者之间的关系有助于深入理解程序运行机制及其潜在性能瓶颈。 ```c #include <stdio.h> int main() { signed char a = -5; printf("Complement of %d is represented as: %hhu\n", a, *(unsigned char*)&a); return 0; } ``` 上述代码展示了如何查看变量 `-5` 在内存中的补码表现形式。 --- ### 总结 综上所述,原码主要用于直观表达数值,便于人类阅读;反码则试图修正某些特定情况下的计算误差;唯有补码因其高效性和兼容性成为主流标准,适用于绝大多数现代电子设备的核心算法逻辑之中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小人物Bobo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值