一、原反补移码概念
正数的原反补码是其本身。
原码:正数不变,负数,符号位 加上 真实值的绝对值,比如-1的绝对值01,那么原码为1000 0001
反码:正数不变,负数,在原码的基础上,符号位不变,其余各位取反。
补码:正数不变,负数,在原码的基础上,符号位不变,其余各位取反 再加1。
移码:和补码的符号位相反其他位相同,也就是对补码最高位取反。
以位长为8为例,正数以1为例,负数以-1为例来理解。
1的原反补码都是0000 0001
-1的原码:1000 0001
-1的反码:1111 1110
-1的补码:1111 1111
-1的移码:0111 1111
注:单片机、计算机中以补码的形式进行计算的。
二、补码的应用以及异或的作用
2.1补码的应用
计算机中,MCU中跑的都是补码,那么在程序代码处理负数时,直接对补码进行取反再加1,正好等于其真实绝对值。这个应用很是广泛。
if(x < 0)
{
B = (~x) +1;
}
B就得到了x的真实绝对值,这就方便了接下来对负数的一系列操作,比如运算什么的。
2.2异或的作用
在单片机中,假如其值长度为12bit,bit0-bit11,最高位bit11为符号位,那么其如果为负数,再假定其值是补码,那么如何处理呢?看下面:
if(x &0x800)
{
B = ((0xFFF)^x) +1;
}
没错,采用异或^运算,将bit0-bit11取反,异或的作用之一就是取反,在单片机中对于寄存器某位的反转可以采用异或的方式,另一个作用是保存组合信息用于交换。例如:
假定给出变量a与b,交换a和b的值,且要求不采用第3个变量,就a与b自身,如何实现?
如下:
a = a^b;/*a作为临时保存变量,保存a和b的所有信息*/
b = a^b;/*异或b将a中的b信息抵消只剩余a信息了,即将a的值赋给b,注意,此时b已经是a了*/
a = a^b;/* 此时b已经是a,异或b即将a中的a信息抵消只剩余b信息了,即将b的值赋给a */
到此就完成了,只用a与b自身不用第3个变量来实现a与b值的互相交换。