6.位运算符的一些巧技

6.1.通过位运算得到内置类型的最小最大值

 1 //获取int型的最大值
 2 //get_int_max_1()可能会报错整型常量溢出
 3 int get_int_max_1() {
 4     return (1 << 31)-1;
 5 }
 6 int get_int_max_2() {
 7     return ~(1 << 31);
 8 }
 9 //unsigned int 是三十二位的数,右移一位除去符号位
10 int get_int_max_3() {
11     return ((unsigned int)-1) >> 1;
12 }
13 //获取int型最小值
14 int get_int_min_1() {
15     return 1 << 31;
16 }

6.2.左移一位和右移一位的作用

1 //这样思考:1111左移一位11110,相当于每一位在原来的基础上+1,也就是说每一位都翻倍了,转换为十进制的时候也就是说两个1111的十进制结果再相加了
2 //左移一位相当于乘以2
3 int multiply_by_two(int num) {
4     return num << 1;
5 }
6 //右移一位相当于除以2
7 int divide_by_two(int num) {
8     return num >> 1;
9 }

6.3.如何乘以2的n次方或者除以2的n次方

1 //m乘以2的n次方
2 int multiply_by_two_power(int m, int n) {
3     return m << n;
4 }
5 //除以2的m次方
6 int divide_by_two_power(int m, int n) {
7     return m << n;
8 }

6.4判断一个数是否是2的幂

1 //判断一个数是不是2的幂
2 bool isFactorialofTwo(int n) {
3     return n > 0 ? (n & (n - 1)) == 0 : false;
4 }
5     /*如果是2的幂,n一定是100... n-1就是1111....
6        所以做与运算结果为0*/

6.5.从原码到补码你应该领悟到,按位取反+1得到了原码的相反数!

1 //求一个数的相反数
2 int opposite_number(int n) {
3     return ~n + 1;
4 }

6.6.统计一个二进制数中0和1的个数 1 //统计一个二进制数中1和0的个数,n&(~n+1)可以得到最后一位为1的二进制数,n|=(n+1)可以使最后一位0置为1

1 int sum_0(int n) {
2     int count = 0;
3     while (n+1)        //全部为1高位去除,结果为0
4     {
5         n |= (n + 1);
6         count++;
7     }
8     return count++;
9 }

6.7.判断一个数的奇偶性

1 //判断一个数的奇偶性
2 //高位去除,得到二进制的最后一位,0为偶数,1为奇
3 bool is_oddnumber(int n) {
4     return (n & 1) == 1;
5 }

6.8.不使用第三个数交换两个数

 1 /交换两个数不使用第三个数,把一般运算符的方法也用上了
 2 //一个数异或本身等于0,一个数异或0得到本身
 3 void swap(int &a,int &b) {
 4     a = a ^ b;
 5     b = a ^ b;
 6     a = a ^ b;
 7 }
 8 void swap_1(int &a, int &b) {
 9     a = a - b;
10     b = a + b;
11     a = b - a;
12 }

6.9.不使用+,-,*,/完成整数相加

 1 int Add(int num1, int num2)
 2 {
 3     int sum, carry;
 4     do {
 5         //将两个数异或,得到不进位的结果
 6         sum = num1 ^ num2;
 7         //将两个位运算,得到进位的结果
 8         carry = (num1 & num2) << 1;
 9         //很显然,我们只要把进位的结果+上不进位的结果就可以得到我们想要的,
10         //但是,我们不能使用+运算符,我们知道,进位的结果是1不断的左移,当进位的结果和不进位的结果不断异或,最左边的1
11         //超过了不进位的结果最左边的1,那么最后一次与运算显然结果为0,于是,最后一次异或运算就是我们想要的相加的结果
12         num1 = sum;
13         num2 = carry;
14     } while (num2 != 0); //将结果相加的过程就重复上述过程,直到进位为0
15 
16     return sum;
17 }

猜你喜欢

转载自www.cnblogs.com/Royzzzzz/p/10975347.html