计算机为何采用补码的形式来表示负数

本文解析了计算机为何采用补码表示负数,通过比较原码、反码和补码,重点阐述了补码如何简化加法运算并解决符号位参与的问题,以及补码在表示范围上的优势。

以下内容转载自 https://www.toutiao.com/i6715969059550134792/

原创算法集市2019-07-21 12:33:18

计算机为何采用补码的形式来表示负数

 

从上文:计算机的原码、反码和补码可知,计算机有三种编码方式来表示同一个数:

  • 原码:符号位加上真值的绝对值,第一位表示符号,其余位表示值。
  • 反码:正数的反码是其本身;负数的反码是在其原码的基础上,符号位不变,其余位取反。
  • 补码:正数的补码还是其本身;负数的补码是在其原码的基础上,符号位保持不变,其余位取反,最后+1。即反码加1。

对于+1和-1,

[+1] = [0001]原 = [0001]反 = [0001]补

[-1] = [1001]原 = [1110]反 = [1111]补

为什么计算机采用补码的形式来表示负数呢?

首先我们知道,一个数在计算机中有正负之分,这个数的最高位(符号位)用来表示它的正负,其中0表示正数,1表示负数。

对于计算机来说,加法是最基础的运算,要设计的尽量简单。

根据加法的运算法则,a-b等于a+(-b)。

如果能将符号位也参与到运算中,而非单独“辨识符号位”,就可以大大简化计算机的基础电路。

计算机为何采用补码的形式来表示负数

 

于是,人们开始探索只保留加法,并将符号位参与到运算中的方法。

1、原码:1 - 1 = 0

首先来看原码:1 - 1 = 0

1 - 1 = 1 + (-1)

= [0001]原 + [1001]原

= [1002]原

= -2

这显然是错误的。

2、反码:1 - 1 = 0

对于反码:

1 - 1 = 1 + (-1)

= [0001]反 + [1110]反

= [1111]反

= [1000]原

= -0

用反码进行计算,发现结果是对的。但有一个问题是“0”的表示有两个:

  • -0([1000])
  • +0([0000])

而0带符号是没有意义的。

且采用补码形式,对于4位的二进制,其表达的范围为:[1000]反~[0111]反,即[1111]原~[0111]原,也即[-7,7]。

因为“0”有两个编码形式,所以等于浪费了一个编码。

3、补码:1 - 1 = 0

而补码解决了反码的问题:

1 - 1 = 1 + (-1)

= [0001]补 + [1111]补

= [0000]补

= [0000]原

= 0

使用补码, 不仅仅解决了0的符号以及存在两个编码的问题,而且还能够用[1000]来表示-8,即多表示一个最低数。

即对于4位的二进制,使用原码或反码表示的范围为[-7,+7],而使用补码表示的范围为[-8,7]。

因为计算机采用补码来表示负数,所以对于编程中常用到的32位int类型,可以表示范围是:[-2^31,2^31-1] 。

计算机为何采用补码的形式来表示负数

 

相关阅读

C语言的数据类型介绍

### 补码表示负数的原理 在计算机中,补码被广泛应用于表示负数。这是因为补码不仅简化了硬件设计,还使得加法器可以统一处理数和负数之间的运算[^1]。具体而言,补码的设计允许将减法转化为加法操作,从而减少了电路复杂度。 #### 符号位的作用 对于有符号整数,最高位通常作为符号位使用。当符号位为`0`时表示数,而符号位为`1`时表示负数[^2]。这一特性决定了补码如何编码数值。 #### 负数补码的生成规则 为了生成一个负数补码,需遵循以下原则: 1. **获取原码**:首先写出该负数对应的绝对值的二进制形式(称为原码)。例如,假设机器字长为8位,则 `-5` 的绝对值 `5` 的二进制形式为 `00000101`。 2. **取反操作**:对除符号位外的所有位执行按位取反操作。继续以 `-5` 为例,对其原码 `00000101` 取反后得到 `11111010`。 3. **加一操作**:最后一步是对取反后的结果加上 `1`。这样,`11111010 + 1 = 11111011` 就是 `-5` 的补码表示[^3]。 此流程总结如下: - 对于任意负数 \( n \),其补码可以通过公式表达为: \[ \text{Complement}(-n) = (\sim |n|_{binary}) + 1 \] 其中,\( |n|_{binary} \) 表示 \( n \) 绝对值的二进制形式;\(\sim\) 表示逐位取反操作。 ### 实现细节与验证 以下是基于 C 语言的一个简单例子展示如何手动计算并验证某个负数补码: ```c #include <stdio.h> void show_bits(int num, size_t bitsize) { unsigned int mask = 1 << (bitsize - 1); while (mask) { putchar(num & mask ? '1' : '0'); mask >>= 1; } } int main() { int number = -5; printf("Binary representation of %d:\n", number); show_bits(number, sizeof(number) * 8); // 显示补码形式 printf("\n"); return 0; } ``` 运行上述代码会打印出 `-5` 在当前平台上的补码表现形式。 ### 计算机为何采用补码? 传统意义上,如果直接存储负数的原码或者反码,在涉及混合负数的操作时会出现逻辑冲突或额外开销。比如简单的加法可能需要区分输入是否包含负数以及调整算法路径[^4]。然而利用补码机制,无论参与运算的是值还是负值都可以通过相同的加法规则完成,极大地优化了处理器架构效率。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值