只要是整数,内存中存储的都是二进制补码

正整数的 原码 反码 补码 相同    000000000000000000000001(32位 1)

负整数 :100000000000000000000001 (32位 -1)

原码 -----> 直接按正负写出的二进制序列

反码 -----> 原码的符号位不变,其他位取反

补码 -----> 反码+1

-2 

原码 : 100000000000000000000010

反码:  111111111111111111111111101

补码:  111111111111111111111111110


更新左/右移操作符

右移操作符

int main() {
int a = 16;

//右移操作符 >>
//移动的二进制位
// 1.算术右移
// 右边丢弃,左边补原符号位
// 符号位是正数,则符号位补0
// 符号位是负数,则符号位补1
// 2.逻辑右移
// 右边丢弃,左边补零
// 除2
//00000000000000000000000000010000 (16)
//00000000000000000000000000001000 向右移到一位
a >> 1;
return 0;
}

左移操作符

int main() {

int a = 5;
//左移操作符 : 左边丢弃 右边补0 乘2的效果
//00000000000000000000000000000101 (16)
//00000000000000000000000000001010
int b = a << 1; // a = 10

return 0;
}

与(&) 或(|)异或(^)

int main() {

// & 按二进制位与
int a = 3;
int b = 5;
int c = a & b;
// 00000011 3
// 00000101 5
// 00000001 1
//1&1为1 1&0 为 0 0&0 为0

//| 按二进制 或
int x = 3;
int y = 5;
int z = x | y;
// 00000011 3
// 00000101 5
// 00000111 8
//1 | 1为1 1 | 0 为 1 0 | 0 为0

//^ 按二进制 异或
//相同位为 0 , 相异为1
int q = 3;
int w = 5;
int e = q ^ w;
// 00000011 3
// 00000101 5
// 00000110 6
//1 ^ 1为0 1 ^ 0 为 1 0 ^ 0 为0
printf("e = %d", e);

return 0;
}

使用异或替换 a和b的值

int main() {

int a = 3;
int b = 5;

printf("before: a = %d, b = %d\n",a,b);
a = a ^ b;
// a 011
// b 101
// a = 110

b = a ^ b;
//110
//101
//011 b =3

a = a ^ b;
//110
//011
//101 a = 5

printf("after: a = %d, b = %d\n", a, b);
return 0;
}

换取二进制 1的数量

int main() {
int a = 0;
int i = 0;
int count = 0;
scanf("%d", &a);

for (i = 0; i < 32; i++)
{
if (1 == ((a >> i) & 1)) {
count++;
}
}
printf("count = %d\n", count);
}

单独修改二进制的一个bit的值

int main() {

int a = 11;

//00000000000000000000000000001011
// |
//00000000000000000000000000000100 (1 << 2)
//00000000000000000000000000001111

a = a | (1 << 2);
printf("%d \n" , a);

a = a & (~(1 << 2));
printf("%d \n", a);

//00000000000000000000000000000100
// ~
//11111111111111111111111111111011
//&
//00000000000000000000000000001111

//00000000000000000000000000001011

return 0;
}