1.逻辑右移与算术右移的区别

https://www.cnblogs.com/zouhong/p/13526845.html

逻辑右移就是不考虑符号bai位,右移一位du,左边补零即可。
算术右移需要考zhi虑符号位,dao右移一位,若符号位为1,就在左边补1;否则,就补0。
所以算术右移也可以进行有符号位的除法,右移,n位就等于除2的n次方。
例如,8位二进制数11001101分别右移一位。
逻辑右移就是[0]1100110
算术右移就是[1]1100110

与C相比, Java 对于如何进行右移有明确的定义。表达是 x>>k 会将 算术右移 位置,而 x>>>k 会对 做逻辑右移。 (待验证)

2.位向量

概念:位向量就是固定长度为w 、由0和1组成的串。位向量的运算可以定义成参数的每个对应元素之间的运算。

位向量应用1:表示有限集合

布尔运算|和&分别对应千集合的并和交,而~对应于集合的补。

https://www.zhihu.com/question/37526794

比如 a=[01101001],从右边数起,第0、3、5、6位是1,所以就表示了0、3、5、6这4个数,b的话同理,对应的是0、2、4、6这4个数。运算 a&b 得到位向量 [01000001], 而AnB={0, 6}

3.Java位运算

https://blog.csdn.net/weixin_37490221/article/details/90905087

Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节类型(byte)等类型。

Java包含了七种位运算符

位运算符 说明
>> 右移运算符,符号左侧数值 按位右移 符号右侧数值指定的位数,若为正数则高位补0,若为负数则高位补1
<< 左移运算符,符号左侧数值 按位左移 符号右侧数值指定的位数,并在低位处补0
>>> 无符号右移运算符,符号左侧数值 按位右移 符号右侧数值指定的位数,无论正负高位补0
& (AND)运算符,对两个整型操作数中对应位执行布尔代数,两个位都为1时输出1,否则0
| (OR)运算符,对两个整型操作数中对应位执行布尔代数,两个位中只要有一个为1就输出1,否则为0
^ 异或(XOR)运算符,对两个整型操作数中对应位执行布尔代数,两个位相等则为0,不相等则为1
~ (NOT)运算符,按位取反运算符翻转操作数的每一位,即0变成1,1变成0

应用场景:

1)判断奇偶性

public void method1(int a){
    if (a&1 == 0) {
        log.info("偶数")
    }else if ( a&1 == 1) {
        log.info("奇数")
    }
}

偶数的最低位肯定是0,奇数的最低位肯定是1,而1的最低位是1其他位都为零,当进行与运算时:

  • 偶数必然:a&1 == 0
  • 奇数必然:a&1 == 1

2)不使用中间变量交换两个数

public void swap(int a , int b) { 
    a = a ^ b;
    b = b ^ a;
    a = a ^ b;
} 

这里需要知道3点:

  1. 任何数和自己进行异或操作结果都为0
  2. 异或符合交换律,即a ^ b = b ^ a
  3. 任何数异或0等于它本身(
    异或的意思是 按位比较,位相同(0,0或1,1)时,结果为0,位不同时(0,1或1,0)结果为1
    所以,0异或任何数A 结果还是A )

好的,那么上面代码操作就等于:

a = a ^ b;
b = b ^ a = b ^ (a ^ b) = a;
a = a ^ b = (a ^ b) ^ (b ^ (a ^ b)) = (a ^ b) ^ a = b;

3) 判断一个正整数是不是2的整数次幂

public boolean power2(int a) {
    if (a <= 0){
        System.out.println("这里不计算负数,直接返回false");
        return false;
    } else{
        return (a&(a-1))==0
    }
}

任何正整数如果是2的幂数,都形如下

10
100
1000
10...0

即首位都为1,往后位数都为0,那么在减去1后(二进制进位、退位)又都形如下

01
011
0111
01...1

所以大于零的2的幂数和自己减一后的数进行与运算结果必然为0

后面还有,就不一一列举了。反正就是位运算可以替代很多的运算符。

4) 掩码运算

取一个byte的高4位和低4位

byte  num =   EncodingUtil.hex2byte(RecData.substring((9 + hLen) * 2, (10 + hLen) * 2))[0];
int hNum = (num & 0xF0) >> 4;
int lNum = num & 0x0F;

位运算其实就是二进制运算,比如num = 33,转成二进制是100001,高位不足补0变成00100001

0xF0转成2进制为11110000

1)取高四位,计算 num & 0xF0:

img

&0xF0:这里F其实就是为了保留高位,0就是低位全部置0.
这样再>>4:(注意:取高位需要右移

img

这样将0010移到低4位,这得到num的高4位的值了。
2)取低四位,num & 0x0F

这个与1)中的原理一样:0是消除位,F是保留位。
取的低4位就是num的低四位,不需要移动。

分类: 基础

0 条评论

发表回复

您的电子邮箱地址不会被公开。