java中的位操作

之前做项目的时候使用位操作不是很多,今天在刷leetcode上题目的时候用到了位操作,是leetcode中的第29题Divide Two Integers

一、java的位操作:

位运算表达式由操作数和位运算符组成,实现对整数类型的二进制数进行位运算。位运算符可以分为逻辑运算符(包括~、&、|和^)及移位运算符(包括>>、<<和>>>)。

1)左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补0)。左移一位(在不溢出的情况下)相当于乘以2。

2)“有符号”右移位运算符(>>)则将运算符左边的运算对象向右移动运算符右侧指定的位数。 “有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。右移一位相当于除以2。

3)Java也添加了一种“无符号”右移位运算符(>>>),它使用了“零扩展”:无论正负,都在高位插入0。

4)若对char,byte或者short进行移位处理,那么在移位进行之前,它们会自动转换成一个int。 只有右侧的5个低位才会用到。这样可防止我们在一个int数里移动不切实际的位数。 若对一个long值进行处理,最后得到的结果也是long。在leetcode这道题目里面需要用到的类型是long。

5)在这6种操作符,只有~取反是单目操作符,其它5种都是双目操作符。

二、java位操作的实际操作:

我们从其他博客里面看到的位操作的举例往往都是给一个数字,然后通过syso进行输出操作。

程序:
public class PlusRightMoving{
public static void main(String[] args){
System.out.println("5>>1="+(>>));
}
}
输出结果:
>>=

但是需要注意的是,如果进行赋值操作和C/C++中是不一样的。

在C/C++中进行左移和右移操作:

div << 1;
res << 1;

但是在java中进行位移操作需要配合赋值操作:

long div = 1;
long res = 1;
while(div < dived){
div = div << 1;
res = res << 1;
}
if(div != dived){
div = div >> 1;
res = res >> 1;
}

如果只是像C/C++中进行操作一样,会不能编译通过。

三、位操作的一些应用题:

1)判断奇偶

只要根据最未位是0还是1来决定,为0就是偶数,为1就是奇数。因此可以用if ((a & 1) == 0)代替if (a % 2 == 0)来判断a是不是偶数。下面程序将输出0到100之间的所有偶数。

2)交换两数

int c = 1, d = 2; 
c ^= d; 
d ^= c; 
c ^= d; 
System.out.println(“c=” + c); 
System.out.println(“d=” + d);

3)变换符号

如对于-11和11,可以通过下面的变换方法将-11变成11

1111 0101(二进制) –取反-> 0000 1010(二进制) –加1-> 0000 1011(二进制)

同样可以这样的将11变成-11

0000 1011(二进制) –取反-> 0000 0100(二进制) –加1-> 1111 0101(二进制)

其他的应用可以参考博客文章:

http://blog.csdn.net/wfzczangpeng/article/details/51819471

其中有很多对java位操作的应用介绍。

上一篇:【BZOJ4736】温暖会指引我们前行(Link-Cut Tree)


下一篇:10 Tensorflow模型保存与读取