第七节课:位运算


1.题目一

在这里插入图片描述
代码实现:


//保证n位0/1的情况下:
//1->0
//0->1
int flip(int n) {
	return n ^ 1;
}

//返回n的符号位:
//n是非负数:返回1
//n是负数:返回0
int sign(int n) {
	return flip((n >> 31) & 1);
}

int getMax01(int a, int b) {//有一个问题:c可能会溢出
	int c = a - b;
	int scA = sign(c);//a-b为非负,scA为1;a-b为负,scA为0
	int scB = flip(scA);//scB与scA相反,一个为0,一个为1

	return a * scA + b * scB;//if语句变成了一个互斥条件相加的形式,替代了判断
}

int getMax02(int a, int b) {解决溢出的问题
	int c = a - b;

	//a b c的符号
	int sa = sign(a);
	int sb = sign(b);
	int sc = sign(c);

	int difSab = sa ^ sb;//a b符号相同为0;不同为1
	int sameSab = flip(difSab);//a b符号相同为1;不同为0

	//返回a的条件:1.a和b符合相同的情况下,a-b>=0,此时a-b不会溢出;2.a和b的符合不相同的情况下,a>0
	int returnA = sameSab * sc + difSab * sa;
	int returnB = flip(returnA);

	return a * returnA + b * returnB;

}

提示:以下是本篇文章正文内容,下面案例可供参考

2.题目二

在这里插入图片描述
2的幂:二进制状态下只有一位是1–>拿到这个数最右侧的1,然后比较与原来的数是否相等,相等就是2的幂;也可以将这个数-1,然后与上这个数,判断是否为0
代码实现:

bool is2Pow(int n) {
	//return (n & (n - 1)) == 0;
	return (n & (~(n - 1))) == n;
}

4的幂:一个数是4的幂的前提必须是2的幂;1的后面跟偶数个0,或者说唯一的1出现在奇数位置上,因此可以通过将这个数和0101…01求&判断是否为0:否,则是4的幂;否则不是。

代码实现:

bool is4Pow(int n) {
									  //0101..01
	return ((n & (n - 1)) == 0) && ((n & 0x55555555) != 0);
}

3.题目三

在这里插入图片描述
加:不进位信息eor:两个数先异或^;进位信息and:两个数求与&,再左移1位。因此a+b<–>eor+and,重复上述操作,直到进位信息为0,则不进位信息就是原始的两数之和

在这里插入图片描述
减:减就是加上相反数,而一个数的相反数就是这个数取反再加一
乘:
在这里插入图片描述
除:将除数尽量左移(假设移了3位),但不要比被除数大,则商的的结果比含有1000因子;然后将被除数减去移动之后的除数,得到的结果当成新的被除数,重复上述操作,直到除数比被除数大;最后将各个移动的位相加,即是最终的商
在这里插入图片描述
或者让除数分别左移31…0位,让被除数尝试去减,假设左移3位可以减,则商的结果中第4位一定是1,然后将被除数减后的结果当作新的被除数,重复上述操作
在这里插入图片描述
代码实现:

//加
int add(int a, int b) {
	int eor = a ^ b;//不进位信息
	int ad = ((a & b) << 1);//进位信息
	while (ad != 0) {
		a = eor ^ ad;
		ad = ((eor & ad) << 1);
		eor = a;
	}
	return eor;
}

//减
int negNum(int n) {
	return add(~n, 1);
}
int minuss(int a, int b) {
	return add(a, negNum(b));
}


//乘
int multi(int a, int b) {
	int res = 0;
	while (b != 0) {
		if ((b & 1) != 0) {
			res = add(res, a);
		}
		a = (a << 1);
		b = ((unsigned)b >> 1);//无符号右移
	}
	return res;
}

//除
bool isNeg(int n) {
	return n < 0;
}

int myDiv(int a, int b) {
	int x = isNeg(a) ? negNum(a) : a;
	int y = isNeg(b) ? negNum(b) : b;
	int res = 0;
	for (int i = 31; i >= 0; i--) {
		if ((x >> i) >= y) {
			res = (res | (1 << i));
			x = minuss(x, (y << i));
		}
	}
	return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值