好久没更新了,今天写一篇关于 反码 补码 运算的文章😊
写这篇博客的原因是进行负数二进制运算的遇到一些问题:
1.硬件上只有加法运算器,那减法该怎么去运算?
2.为什么有补码,它的意义是什么?
讲这几个问题之前,先复习一下反码补码的定义:
- 原码:我们平常表示的二进制数值,其中最高位为符号位 0为正数 1为负数
- 反码:正数的反码还是原码,负数的反码是除了符号位之外,其余位取反
- 补码:正数的补码还是原码,负数的补码则是反码+1
大部分语言一个int整型变量是4个字节,所以一个整型变量就是32位,为了简化运算,接下来所有例子就取8位(其中最高位为符号位)代表一个整型数据进行计算
以 7+8 =15 为例
7 = 0000 0111
8 = 0000 1000 +
··································
0000 1111 = 15
正数的加法很简单,没啥问题,可计算机硬件只有加法运算器(为了让电路设计更简单),所以要减法运算的话就只能引入负数的概念把加法转化为加法。例如: 15-8 = 15+(-8),把8转化为负数然后相加
而计算机并不知道负数是什么,它只知道0 1,所以我们把最高位定为符号位,1就是负数 0就是正数,如1000 0001就是-1
15 = 0000 1111
-8 = 1000 1000 +
··································
1001 0111 = -23
我们会发现结果并不对,其实想想也能明白,负数只对最高位进行处理,就这样相加当然有问题。
由此引入了补码,补码就是正数不变,负数为他的反码+1
比如 -8 的 反码= 1111 0111 补码= 1111 1000 所以:
15 = 0000 1111
-8 = 1111 1000 +
··································
0000 0111 = 原码 =7
溢出的位数自动省略 所以0000 0111的原码就是等于7(因为结果是补码,所以一定要去求他的原码: 正数不变 负数则为-1 求反)
要是觉得不好计算, 求补码也行,因为补码的补码还是原码
为了加强理解在来一个结果为负数的例子
15 - 31 = -16 (下面都是补码进行运算)
0000 1111 = 0000 1111 = 0000 1111
1001 1111 = 1110 0000 = 1110 0001
········································································
1111 0000
因最高位为1 所以原码为该结果 -1 取反= 1110 1111 = 1001 0000 = -16
或者通过求该结果的补码来得到原码 1111 0000 = 1000 1111 = 1001 0000 = -16
补码除了可以计算负数以外 还解决了 0 的唯一性
在原码系统中 1000 0000 和 0000 0000都表示为1 因为0没有正负性
而补码中 只有0000 0000为 0 而1000 0000 等于-128(就是反码+1得到)所以8位数据范围为 -128 - 127 (而不是-127~127)
总结
- 原码:我们平常表示的二进制数值,其中最高位为符号位 0为正数 1为负数
- 反码:正数的反码还是原码,负数的反码是除了符号位之外,其余位取反
- 补码:正数的补码还是原码,负数的补码则是反码+1
- 计算机的减法运算就是将正数转化为负数然后进行相加,运算过程中通过对他们的补码进行运算 ,然后将结果(补码)逆运算成原码,或者将结果进行补码(补码的补码就是原码)也行,即可得出正确值
有用的话麻烦点个赞,感谢大家😘