[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. 在计算机运算的时候都是以 "补码" 的方式来运算的。
相关推荐
学java的小菜鸟啊9 分钟前
第五章 网络编程 TCP/UDP/Socket
java·开发语言·网络·数据结构·网络协议·tcp/ip·udp
我爱吃福鼎肉片12 分钟前
【C++】——list
c++·vector·list
立黄昏粥可温13 分钟前
Python 从入门到实战22(类的定义、使用)
开发语言·python
PerfMan16 分钟前
基于eBPF的procstat软件追踪程序垃圾回收(GC)事件
linux·开发语言·gc·ebpf·垃圾回收·procstat
聆听HJ25 分钟前
java 解析excel
java·开发语言·excel
溪午闻璐28 分钟前
C++ 文件操作
开发语言·c++
LaoWaiHang31 分钟前
C语言从头学61——学习头文件signal.h
c语言
环能jvav大师37 分钟前
基于R语言的统计分析基础:使用SQL语句操作数据集
开发语言·数据库·sql·数据分析·r语言·sqlite
吱吱鼠叔40 分钟前
MATLAB方程求解:1.线性方程组
开发语言·matlab·php
Antonio9151 小时前
【CMake】使用CMake在Visual Studio内构建多文件夹工程
开发语言·c++·visual studio