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板南孚电池拼在一起。)
总结
- 有符号整数二进制的最高位是符号位:0表示正数,1表示负数(相当于把 1 平放就是负号 -,这么好记)。
- 正数的原码反码补码都一样,没有变化。
- 负数的反码是符号位是1,其它位取反。
- 负数的补码是它的反码 + 1
- 0 的反码、补码都是 0 。
- 在计算机运算的时候都是以 "补码" 的方式来运算的。