位操作技巧:正数不取反,负数取反
原理
1) 异或运算法则:异或的两个bit相同结果为1,不同结果为0
2) 一个数^0还是自身, 没有任何效果,因为0^0=0, 1^0=1。
例子:0b0101,1010 ^ 0b0000,0000=0b0101,1010
3) 单个bit^1是取反的效果,0^1=1, 1^1=0,所以一个int变量^0xffffffff就是整个int取反的效果
代码
1) 思路:当符号位为0时,异或0,为1时,异或0xffffffff
2) 不用判断语句实现:正数不取反,负数取反
static void Test(int value) { Console.WriteLine($"{Convert.ToString(value, 2).PadLeft(32, '0')}, 补码"); uint temp = (uint)value; uint signBit = temp >> 31; //强转为无符号数, 是为了右移左侧总是补0 //如果为正数, signBit为0, 变负没有效果, 相当于 value ^ 0 //如果为负数, signBit为1, 再变负, 相当于 value ^ -1, 即: value ^ 0xffffffff, 即为取反 int reverseMask = -(int)signBit; int result = value ^ reverseMask; Console.WriteLine($"{Convert.ToString(reverseMask, 2).PadLeft(32, '0')}, reverseMask"); Console.WriteLine($"{Convert.ToString(result, 2).PadLeft(32, '0')}"); Console.WriteLine(); }
运行后:
static void Main(string[] args) { Test(1); Test(-1); }
运行结果:
2) 上面的代码可以简化为1行
int result2 = value ^ -(int)((uint)value >> 31);