只用位运算来取绝对值 这是一个非常有趣的问题。大家先自己想想吧,Ctrl+A显示答案。 答案:假设x为32位整数,则x xor (not (x shr 31) + 1) + x shr 31的结果是x的绝对值
x shr 31是二进制的最高位,它用来表示x的符号。如果它为0(x为正),则not (x shr 31) + 1等于$00000000,异或任何数结果都不变;
如果最高位为1(x为负),则not (x shr 31) + 1等于$FFFFFFFF,x异或它相当于所有数位取反,异或完后再加一(正数的话等于没加)。
//右移运算 负数在左边添加1,正数在左边添加0
补1的话那补码不是变了吗 -4<<1 怎么还等于-2
因为计算机是以补码来做运算的,平时使用正数的话,正数的补码等于原码没留意而已
-4=10...000100(原)=11...11011(反)=11...11100(补)
-4>>1 = 11..1110(补) = 10...0001(补反)=100...010(补补=原)=-2
异或 1 取反 0 原数
- #include
- int int_abs(int x)
- {
- int y=x>>31;//int 是32位,以补形式存储
- printf("%d\n",y);//11111111 11111111 111111111 11111111这是-1的补码
- return (x^y)-y;//由补码求原码取反加1,-y等于+1
- }
- int main()
- {
- int x=-10,absx;
- absx=int_abs(x);
- printf("%d",absx);
- return 0;
- }
- /*
- -1
- 10Press any key to continue
- 已知一个数的补码,求原码的操作分两种情况:
- (1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。
- (2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取反,然后再整个数加1。
- 例如,已知一个补码为11111001,则原码是10000111(-7):因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”;
- 其余7位1111001取反后为0000110;再加1,所以是10000111。
- */
阅读(3402) | 评论(0) | 转发(0) |