有趣的二进制位操作符

对于有符号数,二进制最高位为符号位
最高位为 0 ,是正数
最高位为 1 ,是负数
原码:直接按数字的正负转换为二进制是原码
反码:原码的符号位不变,其他位按位取反
补码:反码加一,符号位不变。
补码变回原码也可以取反加1,或者减1取反
补码方便负数计算

正数的原反补相同,负数需要经过计算(减一取反)

“%d”有符号数
“%u”无符号数

整数 在内存中存放的是补码 用补码计算,且符号位参与操作符的运算

1)~ 按位取反(符号位改变)

int a=0;
//a的补码00000000 00000000 00000000 00000000
int b=~a;
//a取反后的补码(符号位也取反)11111111 111111111 111111111 111111111 
//此时符号位为1,代表负数,需要计算得到原码
//减1得到反码11111111 11111111 11111111 11111110
//取反得到原码(符号位不变)10000000 000000000 000000000 000000001
printf("%d",b);//打印-1

2)左移操作符<<和右移操作符>>

移动的是存储在二进制中的补码

左移 ’ << ’

左边丢弃,右边补0

右移 ’ >> ’

1.逻辑右移 右边丢弃,左边补0
2.算数右移 右边丢弃,左边原符号补齐

绝大部分为算数右移

int a=1;
int b=<<a;//a不变,b等于2

2.1)左移<<的实际运用

int a=13;
//1101变成1111;把0用1补上
//按位或(|)上0010
//1<<1(1左移1)就是0010
int b =a|(1<<1);
//在把b(1111)变回a(1101)
//按位与(&)上1101
//完整应该为11111111 11111111 11111111 11111101
//上式可以用取反~(1<<1)
int c=b&(~(1<<1))

3)&(按位与)

a=3
b=-2
c=a & b
&(按位与)全11
-2的原码10000000 00000000 00000000 00000010
    反码11111111 11111111 11111111 11111101
    补码11111111 11111111 11111111 11111110
    
 3的补码00000000 00000000 00000000 00000011
 
a&b 补码00000000 00000000 00000000 00000010 (正数的原反补码一样)
结果 2
  

判断的是内存中的补码(负数的补码)

&1可以知道二进制最低一位是0/1
a=a>>1 & 1循环,每一位都判断一下,可以统计有几个1

//计算二进制中1的个数
int count_one_bit(unsigned int n)
{
	int count = 0;
	int i = 0;
	for(i=0; i<32; i++)
	{
		if(((n>>i)&1) == 1)
			count++;
	}
	return count;
}

4)| (按位或)

a=3
b=-2
c=a | b
|(按位或)
-2的补码11111111 11111111 11111111 11111110
 3的补码00000000 00000000 00000000 00000011
 a|b补码 11111111 11111111 11111111 11111111(负数计算)
 反码11111111 11111111 11111111 11111110
 原码10000000 00000000 00000000 00000001
 结果是(-1

5)^ (异或)

a=3
b=-2
c=a ^ b
^(异或)相同为0,相异为1
-2的补码11111111 11111111 11111111 11111110
 3的补码00000000 00000000 00000000 00000011
a^b补码11111111 11111111 11111111 11111101
(负数)
反码11111111 11111111 11111111 11111100
原码10000000 00000000 00000000 00000011
结果(-3

5.1)基于异或(^)的交换两个数(只适用于整型)

a = 3;//011
b = 5;//101
a = a ^ b;
//011^101=110
b = a ^ b;
//110^101=011
a = a ^ b;
//110^011=101
a^a=0
0^a=a
a^a^b=b
a^b^a=b
异或支持交换律
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值