1 原码

原码即计算机的二进制码,特点:

  • 在计算机数据储存中最高位为符号位,正数为0,负数为1

  • 除开最高位,剩余位数代表这个数的绝对值大小

  • 附属的原码是在其数值绝对值基础上再将最高位变为1

例子(原码):

数字 原码
+22 0001 0110
-22 1001 0110
+33 0010 0001
-33 1010 0001

原码的表示简单方便,但是在使用过程中,进行运算时,必须比较二者绝对值大小,才能确定计算结果的正负。所以原码不便于使用。所以一般用补码来进行运算。


2 反码

反码没有赋予功能进行实际使用,他的作用主要是用来过渡补码,作为补码和原码的桥梁。具有以下特点:

  • 对于正数的原码转换为补码,其二进制码不变。
  • 对于负数变为补码,符号位不变(即最高位的1不变),剩余位数变为其相反的数(1变为0,0变为1)

例子(原码和补码转换):

数字 原码 补码
+22 0001 0110 0001 0110
-22 1001 0110 1110 1001
+33 0010 0001 0010 0001
-33 1010 0001 1101 1110

3 补码

补码,才是计算机中用来储存数值的正统血脉。为了方便计算计算机的数值一律使用补码储存。具有以下特点:

  • 在正数中补码与原码和反码相同。
  • 负数中补码符号位不动其他位变为其相反的数,再加1即得到原码。
  • 负数中补码是由其反码+1得到

例子(原码-反码-补码):

数字 原码 反码 补码
+22 0001 0110 0001 0110 0001 0110
-22 1001 0110 1110 1001 1110 1010
+33 0010 0001 0010 0001 0010 0001
-33 1010 0001 1101 1110 1101 1111

4 补码的意义

我们知道0是一个特殊的数字,根据上述三个方式我们可以得到0的两种标答方式即0000 0000来表示(+0)和1000 0000(-0)表示

那么两种方式不同意怎么办?

这时候就凸现出补码的作用了。(-0) 的反码为1111 1111,那么它的补码为1 0000 0000(这时首位的1会被舍去)即若最高位符号位进一那么那个1就会被舍去。

这时(-0)=(+0)=0000 0000。统一了0的编码格式。

那么如果只是统一0的编码格式也没必要制定如此麻烦的规。这时就不得不提到上文所说的数据的运算困难了。对!没错,它对我们计算机的加减运算也大有作用。

不过我们需要记住,在计算机运算加减法中所有的减法也视为加法去计算,如16-6=16+(-8)

我们来看一个例子:

  • 22+33=55 在计算机运算中是这样的 0001 0110 + 0010 0001=0011 0111 我们转化一下$$11+12+14+116+1*32=55$$正好符合问哦们的运算结果。
  • 33-22=33+(-22)=11 在计算机中是这样运算的 0010 0001 + 1110 1010 = 1 0000 1011(这里最高位即符号位进1所以我们直接抹去最高位的1)得到的结果为0000 1011由于符号位为正所以直接转化二进制,得到的数确实为$$18+12+1*1=11$$即为我们所得结果。
  • 22-33=22+(-33)=-11在计算机中是这样运算的 0001 0110 + 1101 1111 = 1111 0101 (结果怎么不对啊!!!(慌张~))这里我们得到的运算结果的符号位为负数,那么我们就要将它转化为原码,先将除了符号位的其他位取反即1000 1010然后我们再加1即 1000 1010+1=1000 1011,我们将他转化为十进制看看:$$11+12+1*8=11$$那么它的大小为11,由于符号位为1,所以他的值为-11.结果正确。

5 数据溢出

看了以上文段,那我们就可以来探究数据溢出是怎么回事了。

首先我们看只有1个字节的情况(char类型),即只有8位。我们知道最高位为符号位,所以8个1/0中能表示数值大小的只有7位,所以最大为0111 1111得到的数值为$$2^7-1$$

即+127,那么如果我们再给它+1会怎么样呢?

即0111 1111 + 0000 0001 = 1000 0000

结果如上,这时候你肯定有疑问了。(什么?!这不是(-0)吗。),但是我们运行一下编译器看看结果如何。如图:

image-20231102222054431

我们运行一下得到结果为

image-20231102222117226

(诶!为什么是这个结果),这里我们就需要知道,符号位为1其他位为0时即为最小值$$-2^7$$

并且我们又可以发现一个事,这里我们直接从最大值变道了最小值,形成了一个闭环。所以我们可以得出char类型的取值范围为(-128)—(127)

那么我们用sizeof找一下其他类型的空间:

image-20231102223151157

输出结果为

image-20231102223232022

  • 所以short有2位即16位二进制,最大值为$$2^{15}-1$$最小值为$$-2^{15}$$

  • int 和long 类型有4位即32位二进制,最大值为$$2^{31}-1$$最小值为$$-2^{31}$$

  • long long 有8位,即64位二进制,最大值为$$2^{63}-1$$最小值为$$-2^{64}$$

所以问哦们在不同情况下使用不同的类型,可以最大化利用电脑资源,使其不备浪费。


资料参考

b站的黑马程序员