[C/C++入门][进制原理]29、整数的二进制,原码,反码和补码

hello,上一次我们了解了计算机中的进制转化和位运算符。

我们现在来讨论一下计算机中整数在计算机中的存储形式,以及所谓的原码,反码,补码的作用。

在计算机科学中,原码、反码和补码是用于表示有符号整数的几种编码方式 。这些编码方式主要应用于二进制数的存储和运算中,涉及到负数的时候,就要用到反码和补码了。下面分别解释这三种编码方式以及它们的作用:

我们需要讨论一下二进制数在内存中的存储形式。

位:

我们把一个0,1,所在的单元格呢,就理解位一位,二八位就构成了一个字节。就比如一个数字0,转化成二进制,最小单位占了一个字节,那就是这么长。把它想象成一组南孚电池,八个电池为一板,一板电池表示一个数字。

|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |

二进制:

一个整数在计算机的存储形式是二进制数,我们称这些二进制数所占的每一个单元成为位,整数是有符号,因此在计算机中用一组字节中的最高位存放符号位,0表示正数,1表示负数.

下面的他们都刚好占

比如:1

|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |

假设:-1(这里是假设,看完后面的就知道了)

|---|---|---|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |

原码

原码是最直观的表示方式,它直接将十进制数转换成二进制数,最高位通常作为符号位,0表示正数,1表示负数。对于正数,原码就是其二进制形式;对于负数,除了最高位表示负号外,其余位表示数值的绝对值的二进制表示。

例如,如果使用8位二进制数表示,那么:

  • +5 的原码是 00000101
  • -5 的原码是 10000101

测试

假设我们使用加法。那么,从计算机中实现-5+5=0;看一下实际的表示

| 加法 | | | | | | | | |
| 5 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
| -5 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |

结果 1 0 0 0 1 0 1 0

如果使用二进制来加,结果变成了10001010,而明显不是0;这说明计算机中负数的存储一定不是按照原码来存储的。

那是怎么存储的呢?

反码

反码是对原码的一种修改。对于正数,其反码与原码相同。而对于负数,除了最高位保持不变(即仍为1,表示这是一个负数)之外,其余各位取反,即0变1,1变0。

例如,继续使用8位二进制数表示:

  • +5 的反码依然是 00000101
  • -5 的反码则是 11111010 (原码 10000101 取反)

加法后的结果仍然不是0,而是11111111;

因此有了:

补码

补码是在反码的基础上再加1得到的。对于正数,其补码与原码相同。对于负数,先计算其绝对值的原码,然后取反(得到反码),最后再加1,得到的就是补码。

例如,同样使用8位二进制数表示:

  • +5 的补码仍然是 00000101
  • -5 的补码计算过程为:先得到原码 10000101,然后取反得到 11111010,最后加1得到 11111011

嘿嘿,这样,正数和负数相加的结果为100000000(一后面8个0)而一个字节表示8位,多的1自然没地方放。就实现了加法。

而这么做的好处呢?

  • 1、简化硬件设计:补码的引入主要是为了简化算术运算,特别是加法和减法运算。在补码表示下,加法和减法可以用同一个电路来实现,这大大简化了处理器的设计。
  • 2、避免重复零:在原码和反码中,0有两种表示形式(+0和-0),而在补码中,0只有一种表示形式(00000000),这避免了零的冗余表示,也简化了逻辑判断。
  • 3、溢出检测:补码的使用使得溢出检测更加简单,特别是在进行加法和减法运算时。

在现代计算机系统中,补码几乎成为表示有符号整数的标准方式。

数据在计算机中如何存储呢

计算机实际只存储补码,所以原码转换为补码的过程,也可以理解为数据存储到计算机内存中的过程:

正数不变,直接就是二进制,而负数将其转换为二进制原码后,再将转换得到的原码进行进制转换为反码,接着补码。

所以计算加法减法的时候,实际上就是两个字节进行了就算。(当然数字大的话,就增加了字节,比如int类型是4个字节,4板南孚电池拼在一起。)

总结

  1. 有符号整数二进制的最高位是符号位:0表示正数,1表示负数(相当于把 1 平放就是负号 -,这么好记)。
  2. 正数的原码反码补码都一样,没有变化。
  3. 负数的反码是符号位是1,其它位取反。
  4. 负数的补码是它的反码 + 1
  5. 0 的反码、补码都是 0 。
  6. 在计算机运算的时候都是以 "补码" 的方式来运算的。
相关推荐
小_太_阳9 分钟前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾12 分钟前
scala借阅图书保存记录(三)
开发语言·后端·scala
唐 城33 分钟前
curl 放弃对 Hyper Rust HTTP 后端的支持
开发语言·http·rust
嵌入式科普1 小时前
嵌入式科普(24)从SPI和CAN通信重新理解“全双工”
c语言·stm32·can·spi·全双工·ra6m5
码银2 小时前
【python】银行客户流失预测预处理部分,独热编码·标签编码·数据离散化处理·数据筛选·数据分割
开发语言·python
从善若水2 小时前
【2024】Merry Christmas!一起用Rust绘制一颗圣诞树吧
开发语言·后端·rust
lqqjuly2 小时前
特殊的“Undefined Reference xxx“编译错误
c语言·c++
冰红茶兑滴水3 小时前
云备份项目--工具类编写
linux·c++
刘好念3 小时前
[OpenGL]使用 Compute Shader 实现矩阵点乘
c++·计算机图形学·opengl·glsl
2401_858286113 小时前
115.【C语言】数据结构之排序(希尔排序)
c语言·开发语言·数据结构·算法·排序算法