操作符和三码(原反补)

1.移位操作符(针对整形):

1.1.左移操作符(<<):

规则:左抛弃,右补0。

在这里插入图片描述

1.2.右移操作符(>>):

规则:1.算数右移:左补0,右丢弃。
2.算数右移:左补符号位,右丢弃。

在这里插入图片描述
--------------------------------------------逻辑右移-------------------------------------------------
在这里插入图片描述
--------------------------------------------算数右移-------------------------------------------------

2.位(二进制位)操作符:

2.1.按位与(&)

规则:两个二进制数同一位为1,进行按位与操作后同位得到1,其余情况均为0。(类似于逻辑中的并)

引申:

a.一个整数按位与1只能得到0或1,等于0时(二进制)最低位为0,等于1时二进制最低位为1。由此可检验一个数的二进制最低位是否为1或者是检验奇偶性。
b.按位与可以实现二进制位1->0,无法实现0->1。
(逻辑中:两个操作数只要有一个为假,结表达式果必为假)。
c.n按位与n-1可以实现n的二进制数位中的一个1变为0(从右往左)。如下例:

求⼀个整数存储在内存中的⼆进制中1的个数。

注:我们应该明确一个整数在内存中存储的是二进制补码(后文将会详细介绍)。
实现方法:
Way1:(整体)移位计数法

思路:二进制最后一位为一(是奇数)则计数一次。将该数除以2,相当于二进制位整体向右移动一位(这里也跟整数除法相呼应:奇数除以二余数舍弃1,偶数除以二相当于余数舍弃0)

#include <stdio.h>
int main()
{
 	int num = 10;
	 int count= 0;//计数
	 while(num)
	 {
		 if(num%2 == 1)
			{
				 count++;
			}
		num = num/2;//可改为num=num>>1;
 	}
 printf("⼆进制中1的个数 = %d\n", count);
 return 0;
}

缺点:无法处理负数的问题。
Way2:数字(1)按位与计数法

思路:将二进制1逐次左移,并按位与原数,如原数二进制位该位为0,则得到的值为0,如原数二进制该位为1,则得到的值为1。由此可作计数标准。

#include <stdio.h>
int main()
{
 int num = -1;
 int i = 0;
 int count = 0;//计数
 for(i=0; i<32; i++)
 {
 if( num & (1 << i) )
 count++; 
 }
 printf("⼆进制中1的个数 = %d\n",count);
 return 0;
}

缺点:循环次数必为32次。
Way3:按位与减一计数法:

思路:将该数与按位与该数减一,实现从右往左去掉一个1,然后用新数重复此操作。有多少个1则执行多少次循环。

在这里插入图片描述

#include <stdio.h>
int main()
{
 int num = -1;
 int i = 0;
 int count = 0;//计数
 while(num)
 {
 count++;
 num = num&(num-1);
 }
 printf("⼆进制中1的个数 = %d\n",count);
 return 0;
}

优点:循环次数最佳。
缺点:不太容易想到。

2.2.按位或(|)

规则:两个二进制数同一位为0,进行按位或操作后同位得到0,其余情况均得到1。(类似与逻辑中的或)

引申:

a.按位或可以实现二进制位的随意改变(0->1/1->0)。

2.3.按位异或(^)

规则:两个二进制数同一位相同则同位得到0,相异则同位得1。

推论:

a.按位异或满足交换律。
b.一个数按位异或自己得到0(相同的两个数进行按位异或操作得到0,这是判断两个数是否相同的办法).按位异或0得到自己。请看下面的例子:

不能创建临时变量(第三个变量),实现两个数的交换

#include <stdio.h>
int main()
{
 int a = 10;
 int b = 20;
 a = a^b;
 b = a^b;
 a = a^b;
 printf("a = %d b = %d\n", a, b);
 return 0;
}

2.4.按位取反(~)

规则:每一位0变1,1变0。(看起来挺简单)

3.原码反码补码:

原码:按照十进制数直接转化为(写出来)的二进制数。
反码:符号位(第一位/最高位)不变,其他为位按位取反。
补码:反码+1.
正数(无符号数)三码相同。
整形数在内存中存的是补码。
补码取反加一也能得到原码。
进行计算和操作的对象是补码。
用printf()打印出来的是原码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

碳酸不酸鸭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值