/*
& :按位与
只有对应的两个二进制位均为 1 时,结果位才为 1,否则为 0
例:
1001 [1*2的0次方 + 0*2的1次方 + 0*2的2次方 + 1*2的3次方 = 9]
0101 [1*2的0次方 + 0*2的1次方 + 1*2的2次方 + 0*2的3次方 = 5]
-----
0001 [= 1]
10111011
10101101
---------
10101001
*/
printf("9 & 5 = %d\n", 9 & 5);//1
/* 用位与&运算符判断变量的奇偶性*/
/*
15: 1111
9: 1001
14: 1110
10: 1010
奇数的最后一个都是 1,偶数的最后一位都是 0
0: 0001
1111
0001
-----
0001
1110
0001
-----
0000
由此可得出:a & 1 == 1//奇数
a & 1 == 0//偶数
*/
int a = 15;
a%2 == 0 ? printf("偶数\n"):printf("奇数\n");//基数
/*
|:按位或
只要对应的两个二进制位有一个为 1 时,结果位就为 1,否则为 0
例:
1001
0101
-----
1101 [=13]
*/
printf("9 | 5 = %d\n", 9 | 5);//13
/*
^:按位异或
当对应的二进制位异或(不相同)时,结果为 1,否则为 0.
1.相同数值进行异或,结果肯定是 0;
2.交换 9^5^6 == 9^6^5
3.任何数值跟 0 进行异或,结果还是原来的数值,9^0 == 9
4.a^b^a == b
例:
1001 [9]
1001 [9]
-----
0000 [=0]
1001 [9]
0101 [5]
-----
1100 [=12]
1001 [9]
0000 [0]
-----
1001 [=9]
*/
printf("9 ^ 5 = %d\n", 9 ^ 5);//12
/*
使用位异或运算符交换两个变量的值
*/
int a = 10;
int b = 11;
/* 借助第三方变量
int temp = a;
a = b;
b = temp;
*/
/*
a = b - a;
b = b - a;
a = b + a;
*/
// a^b^a == b
a = a ^ b;//10 ^ 11
b = a ^ b;//10 ^ 11 ^ 11 = 10
a = a ^ b;//10 ^ 11 ^ 10 = 11
printf("a = %d, b = %d\n",a,b);
/*
~:按位取反
对整数的各二进制数按位取反,即将0变1,1变0,符号位也取反。
例:
1001,写全为
~0000 0000 0000 0000 0000 0000 0000 1001
1111 1111 1111 1111 1111 1111 1111 0110
*/
printf("~9 = %d\n", ~9);//-10
/*左移 <<
1. 对于 a << n,即把整数a 的各二进制位全部左移 n 位,高位丢弃,低位补 0.左移 n 位其实就是乘以 2 的 n 次方;
2. 由于左移是丢弃最高位,0 补最低位,所以符号位也会被丢弃,左移出来的结果值可能会改变正负性。
//参考列
0000 0000 0000 0000 0000 0000 0000 0000
//原始列
0000 0000 0000 0000 0000 0000 0000 1001
//左移一位,末尾用 0 补齐,头部多出的 0 直接去掉
000 0000 0000 0000 0000 0000 0000 10010
//左移两位,末尾用 0 补齐
00 0000 0000 0000 0000 0000 0000 100100
1001 左移一位变为 10010
左移两位变为 100100
即:
9<<1 -> 9 * 2的 1 次方 == 18
9<<2 -> 9 * 2的 2 次方 == 36
9<<n -> 9 * 2的 n 次方
*/
printf("9<<1 = %d\n",9<<1);//18
/*右移 >>
1. 对于 a >> n,即把整数a 的各二进制位全部右移 n 位,保持符号位不变,右移 n 位其实就是除以 2 的 n 次方
2. 为正数时,符号位为 0,最高位补 0
3. 为负数时,符号位为 1,最高位是补 0 或补 1 取决于编译系统的规定
//参考列
0000 0000 0000 0000 0000 0000 0000 0000
//原始列
0000 0000 0000 0000 0000 0000 0000 1001
//第一步:保持符号位不变,符号位后面的全部右移一位,末尾多出的 1 直接去掉
0 000 0000 0000 0000 0000 0000 0000 100
//第二步:空出的一位用符号位补齐,即符号位是 0,则用 0 补齐,符号位是 1,则用 1 补齐
00000 0000 0000 0000 0000 0000 0000 100
1001 右移一位变为 100
右移两位变为 10
即:
8>>1 -> 8 / 2的 1 次方 == 4
8>>2 -> 8 / 2的 2 次方 == 2
8>>n -> 8 / 2的 n 次方
*/
printf("8>>2 = %d\n",8>>2);//2
//输出整数在内存中的二进制形式
- (void)printBinaryWithNum:(int)number
{
//记录现在挪到第几位 (sizeof(number*8)-1) = 31
//number*8 字节数*8 得到总位数
int temp = (sizeof(number)<<3) - 1;
while (temp >= 0) {
int value = number>>temp & 1;
printf("%d\n",value);
temp--;
if ((temp+1)%4 == 0) {
printf(" ");
}
}
}