//整型变量的存储方式以及位运算均以补码方式进行:(正数原码反码补码均相同)

例如:-13

原码:10001101(原码的第一位表示符号位:1表示负数,0表示正数)

反码:11110010(符号位不变其他位取反)

补码:11110011(反码加一)

按位与:全1为1,有0则0

//把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0 。

//那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。(可以用来计算2进制数中1的个数)
int Count(int n) { int num = 0; while (n) { n &= (n - 1); num++; } return num;
}

//与运算一用途:取一个数中指定位。找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。例:设X=10101110,取X的后4位,用
X & 0000 1111 = 0000 1110 即可得到;还可用来取X的2、4、6位。

按位或:有1则1,全0为0

负数进行按位操作后得到的依然为补码:若要求其具体值还要转换成原码
int main() { int a = 8; int b = -3; // 8的原码:00000000000000000000000000001000
// -3的原码:10000000000000000000000000000011 //
反码:11111111111111111111111111111100 // 补码:11111111111111111111111111111101 //
8的补码为:00000000000000000000000000001000 //8 |
-3得到:11111111111111111111111111111101(得到补码)
//转换为原码:10000000000000000000000000000011(即为二进制的-3) int c = a | b;
printf("%d\n", c);//输出-3 return 0; }
按位异或^:相同为0,相异为1

按位异或的3个特点:

(1) 任何数字异或它自己都等于0;

(2) 0异或任何数,等于任何数;

(3) 1异或任何数,等于取反任何数。

//进行异或运算时,当前位的两个二进制表示不同则为1相同则为0.该方法被广泛推广用来统计一个数的1的位数!
int main() { int n = 0; int i = 0; int count = 0; scanf("%d", &n); for (i = 0;
i < 32; i++) { if ((n ^ 1) == n - 1)//如果最后一位为1则异或1后小1; count++; n >>= 1;//右移一位
} printf("%d\n", count); return 0; }
//异或运算也可进行两个数的交换(不需要创建新的变量):
int main() { int a = 3; int b = 5; printf("a=%d b=%d\n", a, b); a = a ^ b; b =
a ^ b; a = a ^ b; //类似于加减法中的: //a = a + b;   b = a - b; a = a -b; printf("a=%d
b=%d\n", a, b); return 0; }
利用异或的三个特点也可以解决某些问题:

如:1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;

正常解法这里就不说了,而且如果数字较大了话正常解法可能造成栈溢出,利用异或的特点1也可以迅速把它找出来。
int main() { int arr[1001] = { 5 }; int i = 0; int x = 0;//存储重复的数字 for (i = 1;
i < 1001; ++i) arr[i] = i;//得到1-1000且只含有一个重复数字的数组 int j = 0; for (j = 0; j <
1001; j++) x = x^ arr[j];//首先对数组内每个元素异或一遍 for (j = 1; j < 1001; j++) x = x ^
j;//对1-1000的数字异或一遍 //这里相当于1-1000中除了重复那个其他数字均异或两遍, // 根据特点1、2可以得出x的值即为重复元素的值
printf("%d\n", x); }

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信