C++ 位运算技巧

可以使用C对变量中的个别位进行操作。您可能对人们想这样做的原因感到奇怪。这种能力有时确实是必须的,或者至少是有用的。C提供位的逻辑运算符和移位运算符。

1. 位运算符

  1. 位运算符
    1. 取反 ~,对于每个位按位取反。
    2. 位与 &,对于每个位,只有两个操作数的对应位都是 1 时结果才为 1。
    3. 位或 |,对于每个位,如果其中任意操作数中对应的位为 1,那么结果位就为 1。
    4. 位抑或 ^,二进制运算符^对两个操作数逐位进行比较。如果都是0或者都是1,则结果位0, 两个不一样则为1。
  2. 移位运算符
    1. 左移 <<,按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补 0。
    2. 右移 >>,按二进制形式把所有的数字向右移动对应位移位数,低位移出(舍弃),高位的空位补符号位,即正数补 0,负数补 1
// 1. 取反
void test01()
{
	int num1 = 2;

	//1. 按位取反
	// 11111111 11111111 11111111 11111101
	// 10000000 00000000 00000000 00000010
	// 10000000 00000000 00000000 00000011
	// 负数在计算机中是以补码形式存储
	int ret = ~num1;
	printf("ret = %d\n", ret);
}

// 2. 位与
void test02()
{
	int num1 = 2;
	int num2 = 3;
	// 00000000 00000000 00000000 00000010
	// 00000000 00000000 00000000 00000011
	// 00000000 00000000 00000000 00000010
	int ret = num1 & num2;
	printf("ret = %d\n", ret);
}

// 3. 位或
void test03()
{
	int num1 = 2;
	int num2 = 3;
	// 00000000 00000000 00000000 00000010
	// 00000000 00000000 00000000 00000011
	// 00000000 00000000 00000000 00000011
	int ret = num1 | num2;
	printf("ret = %d\n", ret);
}

// 4. 位抑或
void  test04()
{
	int num1 = 2;
	int num2 = 3;
	// 00000000 00000000 00000000 00000010
	// 00000000 00000000 00000000 00000011
	// 00000000 00000000 00000000 00000001
 	int ret = num1 ^ num2;
	printf("ret = %d\n", ret);
}

// 5. 左移
void test05()
{
	int num = 2;
	// 00000000 00000000 00000000 00000010 << 2
	// 00000000 00000000 00000000 00001000
	int ret = num << 2;
	printf("ret = %d\n", ret);
}

// 6. 右移
void test06()
{
	int num = 11;
	// 00000000 00000000 00000000 00001011  >> 2
	// 00000000 00000000 00000000 00000011
	int ret = num >> 2;
	printf("ret = %d\n", ret);
}

2. 位运算技巧

// 1.判断数的奇偶性
void test()
{
	int num = 2;
	// 00000000 00000000 00000000 00000011 &
	// 00000000 00000000 00000000 00000001
	// 00000000 00000000 00000000 00000001
	printf("%s\n", num & 1 == 1 ? "奇数" : "偶数");
}

// 2.获得整型最大值
void test()
{
	// 00000000 00000000 00000000 00000001
	// 10000000 00000000 00000000 00000000
	// 01111111 11111111 11111111 11111111
	printf("%d\n", (1 << 31) - 1);
	// 01111111 11111111 11111111 11111111
	printf("%d\n", ~(1 << 31));
}

// 3.计算乘以2、除以2**
void test()
{
	int num = 6;
	// 00000000 00000000 00000000 00000110 << 1
	// 00000000 00000000 00000000 00001100
	printf("%d\n", num << 1);
	// 00000000 00000000 00000000 00000110 >> 1
	// 00000000 00000000 00000000 00000011
	printf("%d\n", num >> 1);
}

// 4.从低位到高位,取 v 的 m 位**
void test()
{
	int v = 8; // 取v的第4位
	int n = 4;
	// 00000000 00000000 00000000 00001000
	printf("%d\n", (v >> (n - 1)) & 1);
	// 00000000 00000000 00000000 00000001
	// 00000000 00000000 00000000 00000001
	// 00000000 00000000 00000000 00000001
}

// 5.交换两个数
void test()
{
	int num1 = 2;
	int num2 = 3;

	// 00000000 00000000 00000000 00000010
	// 00000000 00000000 00000000 00000011
	// 00000000 00000000 00000000 00000001 
	// num1 或者 num2 抑或这个值得到另外一个值

	num1 = num1 ^ num2;
	num2 = num1 ^ num2;
	num1 = num1 ^ num2;

	// num1 ^= num2 ^= num1 ^= num2;

	printf("num1=%d num2=%d\n", num1, num2);
}
未经允许不得转载:一亩三分地 » C++ 位运算技巧
评论 (0)

6 + 2 =