位操作技巧:正数不取反,负数取反

原理

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);

 

posted @ 2022-11-19 22:31  yanghui01  阅读(89)  评论(0编辑  收藏  举报