在计算机中为了简化CPU的运算,CPU只有加法器,没有减法器,但是减法运算也可以,因为减一个数可以表示为加一个负数,比如5-3,实际上是做了 5+(-3)

实际上这个叫做补码运算,就是减去一个数,相当于加上了这个数的负数。

但是直接加负数不方便,我可以加上这个负数的补码。

·首先需要了解一下 原码、反码、补码的概念

可以将计算机中的数据分为以下几种

首先来看 有符号数据 在计算机中如何表示。需要关注两个问题

  • 符号如何表示
  • 小数点如何表示

对于符号:采用将符号数值化

也就是用数字0、1分别代表正号负号,并放在数值的最高位

对于小数点:采用两种方式的一种

1)定点数:约定小数点隐含在某一位置上

2)浮点数:小数点可以任意浮动

不管采用哪种方式,小数点在计算机中并不占用某个数位

计算机中需要用二进制来表示,带符号数据也不例外




当我们把其它进制的数表示成二进制数的时候,它可以表示为 原码、反码、补码

·原码:最高位表示数的符号,其他位表示数值

例: +7的原码=00000111B

首先用0来表示正号(符号部分),然后再把十进制的7转换成二进制:111(数值部分)
假定计算机存储字长是八位,那么现在不足八位,我们就在数值部分的最前面添加4个0;(以下全文都假定是八位)

最后可得到+7的原码是00000111B 其中最前面的这个0代表正号,这个B是代表这个是二进制的数(可以去掉,只是提醒我们这个是个二进制的数)

同理,-7的原码=10000111B ;1代表的是负号




·反码:

正数的反码和原码相同。例如: +7的反码=00000111B=+7的原码

负数的反码是原码的符号位不变其余位按位取反

例:-7的反码,首先我们写出-7的原码10000111B

刚刚提到过,最前面的一位表示符号位,负数的反码符号位不变,1不变

其它位按位取反(0变成1,1变成0)也就是 1111000

再把符号位加上,最后得到 -7的反码是 11111000B




·补码:

正数的补码和原码相同。例:+7的补码=00000111B=+7的原码

负数的补码是由其原码的符号位不变,其余位按位取反,再在最低位加1

例:-7的补码。首先写出-7的原码10000111B

符号位(最高位)不变,还是1;其余位按位取反 1111000

最后再在最低位加1,也就是1111001

最后加上符号位,得到-7的补码是 11111001B




回到文章最开头的地方,我们计算5-3,也就是5加上3的补码

首先5的二进制是101

-3的补码,不看它的负号,3的二进制是011

按位取反:100
再加1: 101

相当于 5-3=5+(-3的补码)
=101+101
=1010

进位的这一位(最高位)发生了溢出所以去掉它,最后剩下010,010就是2




3和-3 怎么表示,3表示为011,-3表示为它的补码,也就是101。观察两个数我们可以发现,其实求一个数的相反数,就是把这个原来的数按位取反再加1。汇编里面就是NEG指令




在汇编里面有很多指令区分了有符号数和无符号数,怎么理解呢

计算机不会自己判断你给的这个数是啥类型,它只会执行代码,你让它把这个数看成有符号的它就是有符号的,你当它是无符号的就是无符号的。

在汇编里面运算结果影响进位标志和溢出标志,如果你程序员认为这是无符号运算,那么就只考虑进位标志而忽略溢出标志;如果你认为这是有符号运算,则只考虑溢出标志而忽略进位标志

最后修改:2022 年 03 月 08 日
如果觉得我的文章对你有用,请随意赞赏