抑郁症健康,内容丰富有趣,生活中的好帮手!
抑郁症健康 > 位运算符+位运算的应用

位运算符+位运算的应用

时间:2020-09-23 22:22:32

相关推荐

目录

一:位运算符

1:按位与&

2:按位或|

3:按位取反~

4:按位异或

5:移位

1.左移<<:

2.右移>>:

6:码

1.原码:

2:反码:

3:补码:

二:位运算实战

1:判断奇偶数

2:判断二进制位是1还是0

3:交换两个数的值(不使用第三个变量无加减乘除)

4:找出那个落单的数

附加:力扣题:只出现了一次的数字

5:二进制中1的个数

6:2的幂

7:颠倒二进制位

一:位运算符

1:按位与&

类似与数学里的交集,只有两个数都是1时,按位与的结果才是1,否则是0

例如 :

2:按位或|

相当于数学里的并集,只有两者中有一个为1,那么它们或的按位或的结果就是1

例如:

3:按位取反~

即0取反后变成1,1取反后变成0

例如:

4:按位异或

相同的数字异或为0,相异的数字异或为1

例如:

5:移位

移位能使程序的运行效率更高,可代替乘除法

1.左移<<:

最左侧不要了,最右侧直接补0;(左移相当于乘法,如左移1位,相当于乘以2的1次方)

2.右移>>:

最右侧不要了,最左侧直接补0;(右移相当于除法,如右移1位,相当于除以2的1次方)

6:码

1.原码:

将这个数字按照正负数的形式翻译成二进制

2:反码:

正数的反码是它本身

负数的反码是(除了符号位不变)其他的位置的是原码取反

3:补码:

正数的补码是它本身

负数的补码是它的反码+1

例如:

int a = 10; //整型a是4个字节,32位// 00000000 00000000 00000000 00001010 - 原码// 00000000 00000000 00000000 00001010 - 反码// 00000000 00000000 00000000 00001010 - 补码int b = -10;// 10000000 00000000 00000000 00001010 - 原码// 11111111 11111111 11111111 11110101 - 反码// 11111111 11111111 11111111 11110110 - 补码

在进行位运算时:是以补码的形式进行计算的,输出的结果是补码进一步转换成原码输出的

二:位运算实战

1:判断奇偶数

题目:输入一个数字,判断它是奇数还是偶数,用位运算来实现

解析:我们首先要知道,我们输入的数字是10进制,在计算机中是2进制,那么2进制转10进制是该位数字*2^(n-1) n表示的是它在第几个位置

比如:

我们发现只有最后有机会去决定正负,因为是1或者0乘2的0次方(也就是1)

如果最后一位是1,那么它就是奇数

如果最后一位是0,那么它就是偶数

现在的问题就转变为:如何知道最后一位是1,还是0?

想想我们之前的位运算符,这就是我们的武器= = :答案是让1去&这个数num

如果是答案是1,那么我们就可以知道,num这个数的第一位就是1

如果答案是0,那么我们就可以知道,num这个数的第一位就是0

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>int main(){int num = 0;scanf("%d", &num);if ((num & 1) == 1){printf("%d是奇数", num);}else{printf("%d是偶数", num);}return 0;}

2:判断二进制位是1还是0

题目:给出一个数,让你判断它的某一位是0还是1

比如这里这个数我们定为76,然后我们要判断这个数的第3位是0还是1

思路解析:

其实也还是很简单,我们题目既然要我们求的是第3位,那么我们就只需把这个数字右移2位,然后用1&这个数字就可以了

如果答案是1,那么这个数字的第三位就是1,反之则为0

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>int main(){int num = 76;int temp = num;int k = 3;num = num >> (k - 1);if ((num & 1) == 1){printf("%d的第%d个位置的数字是1", temp, k);}else{printf("%d的第%d个位置的数字是0", temp, k);}return 0;}

3:交换两个数的值(不使用第三个变量无加减乘除)

这个方法比较难想,先上答案把

想不明白的同学将a,b代进去就可以理解了= =

异或就像消消乐,只有偶数倍个数的数字出现都为被消掉

4:找出那个落单的数

一个数组中除了某一个元素中之外,其他的元素都出现了两次,写程序找出这份只出现一次的数字

看到有两次,找一个,马上就要想到异或,直接消消乐

#include<stdio.h>int main(){int arr[] = { 1,1,2,3,3,4,4,5,5 };int n = sizeof(arr) / sizeof(arr[0]);int x = 0;for (int i = 0; i < n; i++){x = x ^ arr[i];}printf("%d\n", x);return 0;}

附加:力扣题:只出现了一次的数字

代码实现:

int singleNumber(int* nums, int numsSize){int ret = 0;for (int i = 0; i < numsSize; i++){ret = ret ^ nums[i];}return ret;}

5:二进制中1的个数

思路解析:

我们在前面已经知道了如何判断第一个位的数字是1还是0,那么我们只需在一个循环里,一次移动移位,共32次,如果遇到了为1,那么就让计数器++,返回计数器即可

int hammingWeight(uint32_t n) {int result = 0;for (int i = 1; i <= 32; i++){if (n & 1 == 1){result++;}n >>= 1;}return result;}

6:2的幂

思路解析:

先自己用二进制表达一下,2的幂,2^1,2^2,2^3

你会发现它们的共同点是,最高位是1,其余为都是0

这个时候有一个特别神的方法:将n&(n-1),如果为0,则说明n是2的幂,反之不是

画图理解:

但是还得有一个条件约束,就是n>0,因为这个题目条件其实要求的是n为正数的情况= =

bool isPowerOfTwo(int n){return (n>0) && (n&(n-1))==0;}

一行足以

7:颠倒二进制位

思路解析:

开一个新的数ret,将它+n这个数二进制位的第一个数,并让ret左移1,让n右移1,循环32次,这样就实现了倒转

代码实现:

uint32_t reverseBits(uint32_t n) {uint32_t ret = 0;for (int i = 0; i < 32; i++) {ret <<= 1;ret += (n & 1);n >>= 1;}return ret;}

如果觉得《位运算符+位运算的应用》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。