在计算机中,所有的数据最终是以二进制的形式进行相应的表达的。那么正数和负数是如何进行保存的呢?
在计算机中,正数的保存就是其二进制进行保存。对于负数,则是以补码的形式进行保存。说到补码,先从原码和反码说起。
原码:就是一个整数,按照绝对值的大小转化为二进制数。
反码:就是将二进制数安慰取反,得到的二进制数,就是原二进制的反码。
补码:反码加1就是补码。
关于原码
和补码之间的关系,可以如下:
【X+Y】补=【x】补+【y】补
【X-Y】补=【x】补+【-y】补
【【x】补】补
=
【x】原
计算机对于减法操作其实是通过运用补码进行的,也就是减法变成补码的相加。
(Unsigned char)1 – (unsigned char)254 = 2
0000
0001
0000 0001
--
1111 1110
取补
+ 0000
0001
0000 0002
(unsigned char)1 – (unsigned char)2 =
0000
0001
0000 0001
-
0000 0010
取补
+
1111 1110
1111 1111
如果输出按照singed
的话,1111
1111的原码为1000 0001
即为-1
如果输出是按照unsigned类型的话,
1111 1111
即为255
通过下面的程序进行验证,输出的结果正好是预期的结果。
int
main()
{
unsigned char a = 1, b=2;
printf("%d\n", (signed char)(a-b));
printf("%d\n", (unsigned char)(a-b));
}
http://s6/middle/694f2ae7gca6a20fceae5&690SUB指令操作" TITLE="CPU SUB指令操作" />
因此,CPU
SUB指令在对于unsigned
的做减法的操作的时候,其实不管是singed
或者unsigned的操作,都是通过补码的加法进行的。得到的数据输出也是如果是强制转换为singed的话,那么最高为就作为相应的符号位。具体的输出的数据是根据要求的类型进行相应的转化的。
再看下面的程序,在unsigned
的减法处理中,最高为的符号转化,要注意。有的时候小数减去大数可能得到一个正数。
int
main()
{
unsigned char a = 1, b=130, c= 129;
printf("%d\n", (signed char)(a-b));
printf("%d\n", (signed char)(a-c));
}
http://s1/middle/694f2ae7gca6a21cb92f0&690SUB指令操作" TITLE="CPU SUB指令操作" />
加载中,请稍候......