位运算

位运算

一、什么是位运算?
我们知道程序中的所有数在计算机内存中都是以二进制的形式储存的。那位运算就是直接对整数在内存中的二进制位进行操作。
二、位运算运算符
在这里插入图片描述
三、应用详解
(1)&(按位与运算符)
例子:若a=2 、b=4,则a&b的结果如下:a的二进制表示:0010b的二进制表示:0100那么a&b=0000,结果就是0。

用途:
1、清零:任何数&0都为0
2、判断奇偶数:当一个数的二进制数最低位的值为1的时候是奇数,最低位为0 就是偶数,那么,一个数&1的结果是0的话,那这个数就是个偶数。

(2)|(按位或运算符)
例子:若a=2 、b=4,则a|b的结果如下:a的二进制表示:0010b的二进制表示:0100那么a&b=0110,结果就是6。

(3)^(异或运算符)例子:若a=2 、b=4,则a^b的结果如下:
a的二进制表示:0010b的二进制表示:0100那么a^b=0110,结果就是6。

用途:可以用来交换两个数:
例如a=0010,b=0100
a=a^b=0110 b=b^a=0010 a=a^b=0100

(4)~(取反运算符)
例子:若a=2则a的结果如下:a的二进制表示:0010那么a=1101,结果就是13。

(5)<<(左移运算符)将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。
设 a=0010,a = a<< 1 将a的二进制位左移1位、右补0,即得a=0100。若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。

(6)>>(右移运算符)将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。
例如:a=0010,a=a>>1 将a的二进制位右移1位,左补0,得到a=0001操作数每右移一位,相当于该数除以2。
(7)>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0

四、力扣题目
题目描述:编写一个方法,找出两个数字a和b中最大的那一个。不得使用if-else或其他比较运算符

方法一:
平均值法: max(a, b) = ((a + b) + abs(a - b)) / 2。
其实原理也好理解:我们用数轴就可以清晰的表达
我们假设a=1,b=4那么他们在数轴上的位置如下:
在这里插入图片描述
a+b其实就相当于把a的距离在复制多一份出来,我们复制出来的a这份加到b坐标之后去
在这里插入图片描述
a-b的绝对值相当于a与b之间的距离,我们把这份距离的部分也复制出来继续往后加
在这里插入图片描述
这个时候我们就能发现b刚好处于中点的位置,所以 max(a, b) = ((a + b) + abs(a - b)) / 2。
但是:这道题要考虑溢出问题。显然不考虑溢出是无法通过的。

什么叫溢出呢?
溢出就是运算结果超出了机器数所能表示的范围
两个同号数相加两个异号数相减有可能会溢出
正溢:正+正=负
负溢:负+负=正

解决方法:转为long类型,这样就不需要考虑int型的溢出了,因为把数据表达的范围变大了。

long sum=(long)a+b;
long diff=(long)a-b;
return (int)((sum + Math.abs(diff))/2); 

方法二:不考虑溢出问题,同号选大,异号选正

 //判断a>b还是b>a,如果a>b,k=0,否则k=1
 //>>>31是为了取符号位,负数为1,整数为0
  int k=(a-b)>>>31;
  int ap=a>>>31;
  int bp=b>>>31;
  //判断ab是否异号
   int p=ap^bp;//(相同为0,相异为1)
   k=k&(p^1)|ap&p;
   k = k&(p^1)|ap & p ;
   /* k&(p^1)决定的是ab同号k的取值;
   ap & p 判断的是ab异号是k的取值。
   其实为了逻辑上好理解一些,可以把&符号看成“且”,|符号看成“或”
   &两个为1才为1,|两个为0才为0*/
   return b*k+a*(k^1);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值