在计算机中为了简化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指令
在汇编里面有很多指令区分了有符号数和无符号数,怎么理解呢
计算机不会自己判断你给的这个数是啥类型,它只会执行代码,你让它把这个数看成有符号的它就是有符号的,你当它是无符号的就是无符号的。
在汇编里面运算结果影响进位标志和溢出标志,如果你程序员认为这是无符号运算,那么就只考虑进位标志而忽略溢出标志;如果你认为这是有符号运算,则只考虑溢出标志而忽略进位标志
1 条评论
[…] 汇编(22)原码/反码/补码/有符号数和无符号数 […]