[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. 在计算机运算的时候都是以 "补码" 的方式来运算的。
相关推荐
待什么青丝16 分钟前
【TMS570LC4357】之相关驱动开发学习记录2
c语言·arm开发·驱动开发·单片机·学习
小柯博客16 分钟前
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
c语言·stm32·单片机·嵌入式硬件·物联网
开发者工具分享21 分钟前
如何应对敏捷转型中的团队阻力
开发语言
gregmankiw27 分钟前
C#调用Rust动态链接库DLL的案例
开发语言·rust·c#
roman_日积跬步-终至千里42 分钟前
【Go语言基础【20】】Go的包与工程
开发语言·后端·golang
秦少游在淮海1 小时前
C++ - string 的使用 #auto #范围for #访问及遍历操作 #容量操作 #修改操作 #其他操作 #非成员函数
开发语言·c++·stl·string·范围for·auto·string 的使用
const5441 小时前
cpp自学 day2(—>运算符)
开发语言·c++
心扬1 小时前
python生成器
开发语言·python
阿蒙Amon1 小时前
06. C#入门系列【自定义类型】:从青铜到王者的进阶之路
开发语言·c#
虾球xz1 小时前
CppCon 2015 学习:CLANG/C2 for Windows
开发语言·c++·windows·学习