[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. 在计算机运算的时候都是以 "补码" 的方式来运算的。
相关推荐
wjs20243 分钟前
MongoDB 更新集合名
开发语言
monkey_meng6 分钟前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
一只小小汤圆10 分钟前
opencascade源码学习之BRepOffsetAPI包 -BRepOffsetAPI_DraftAngle
c++·学习·opencascade
legend_jz31 分钟前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
嘿BRE41 分钟前
【C++】几个基本容器的模拟实现(string,vector,list,stack,queue,priority_queue)
c++
tangliang_cn1 小时前
java入门 自定义springboot starter
java·开发语言·spring boot
程序猿阿伟1 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
新知图书1 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
威威猫的栗子1 小时前
Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画
开发语言·python
力透键背1 小时前
display: none和visibility: hidden的区别
开发语言·前端·javascript