Java 位运算和运算符总结

来源:互联网 发布:西班牙失业率数据 编辑:程序博客网 时间:2024/05/16 13:39

此文大部分内容来自 http://blog.csdn.net/is_zhoufeng/article/details/8112199 (感谢作者) 此文是在作者及网络基础上的总结,希望可以帮助还不了解位运算的同学

在了解位运算前,先学习一下数据类型与大小,这对我们位运算很有帮助。

 1.各数据类型占的字节数(这是 Java 类型的,C 的不一样)

Int:       4 字节
Short:     2 字节
Long:      8 字节
Byte:      1 字节
Character: 2 字节
Float:     4 字节
Double:    8 字节
System.out.println("Integer: " + Integer.SIZE / 8);     // 4System.out.println("Short: " + Short.SIZE / 8);         // 2System.out.println("Long: " + Long.SIZE / 8);           // 8System.out.println("Byte: " + Byte.SIZE / 8);           // 1System.out.println("Character: " + Character.SIZE / 8); // 2System.out.println("Float: " + Float.SIZE / 8);         // 4System.out.println("Double: " + Double.SIZE / 8);       // 8

 2.再来看数据在计算机中的表示形式,因为计算机只识别二进制数据,0 与 1,如下:
我们看 int 值为 5 的机器表示:
00000000 00000000 00000000 00000101
5 转换成二进制是 101,不过 int 类型的数占用 4 字节(32 位),所以前面填了一堆 0。

 3.字节的大小概念

1字节 = 8bit(即 8 个占位符)

由此我们可以看出,4 字节即 4 组 8 bit 的 0 与 1 组成

 4.Java 中 int 型最大数
因为计算内部处理是二进制,int 占 4 字节所以最大就是 32 个 1 的二进制数,但是,机器用最高位 0 与 1 标记正负值,所以最大就是 31 个 1 ,如下:
01111111 11111111 11111111 11111111
将上面二进制数转换成十进制后为:2147483647

一、位运算简介
 Java 位运算主要有四种:与(&)、非(~)、或(|)、异或(^)
1.与(&)运算符
与运算符用符号“&”表示,其使用规律:两个操作数中位都为 1,结果才为 1,否则结果为 0,例如下面的程序段。

private static void and() {    int a = 129;    int b = 128;    System.out.println("a 和 b 与的结果是:" + (a & b));}

【运行结果】
a 和 b 与的结果是:128


  下面分析这个程序:
“a”的值是 129,转换成二进制就是 10000001,而“b”的值是 128,转换成二进制就是 10000000。根据与运算符的运算规律,只有两个位都是 1,结果才是 1,可以知道结果就是 10000000,即 128。


2.或(|)运算符
或运算符用符号“|”表示,其运算规律:两个位只要有一个为 1,那么结果就是 1,否则就为 0,下面看一个简单的例子。

private static void or() {int a = 129;int b = 128;System.out.println("a 和 b 或的结果是:" + (a | b));}
【运行结果】
a 和 b 或的结果是:129


  下面分析这个程序段:
a 的值是 129,转换成二进制就是 10000001,而 b 的值是 128,转换成二进制就是 10000000,根据或运算符的运算规律,只有两个位有一个是 1,结果才是 1,可以知道结果就是 10000001,即 129。

3.非(~)运算符
非运算符用符号“~”表示,运算规律:如果位为 0,结果是 1,如果位为 1,结果是 0,下面看一个简单例子。
private static void not() {int a = 2;System.out.println("a 非的结果是:" + (~a));}
【运行结果】
a 非的结果是:-3

4.异或(^)运算符
异或运算符是用符号“^”表示的,其运算规律是:两个操作数的位中,相同则结果为 0,不同则结果为 1。下面看一个简单的例子。
private static void xor() {int a = 15;int b = 2;System.out.println("a 与 b 异或的结果是:" + (a ^ b));}
【运行结果】
a 与 b 异或的结果是:13

分析上面的程序段:a 的值是15,转换成二进制为1111,而 b 的值是 2,转换成二进制为 0010,根据异或的运算规律,可以得出其结果为 1101 即 13。

二、运算符(操作符)总结

1.Java 中有以下运算符,并按优先级顺序排列。
优先级运算符分类结合顺序运算符由

分隔符左结合.    []     ( )     ;      ,一元运算符右结合!  ++     --     -   ~

算术运算符

移位运算符

左结合*     /      %    +     -      <<   >>   >>>关系运算符左结合<     >     <=   >=   instanceof(Java 特有)   = =  !=逻辑运算符左结合! &&  ||  ~  &  |  ^ 三目运算符右结合布尔表达式?表达式1:表达式2赋值运算符右结合=  *=     /=  %=   +=   -=    <<= >>= >>>=  &=  *=  |=

一、一元运算符
因操作数是一个,故称为一元运算符。
运算符含义例子-改变数值的符号,取反-x(-1*x)~逐位取反,属于位运算符~x++自加1x++--自减1x--
++x 因为++在前,所以先加后用。
x++ 因为++在后,所以先用后加。


注意:a+ ++b 和 a+++b 是不一样的(因为有一个空格)。

int a = 10;
int b = 10;
int sum = a+ ++b;
System.out.println("a=" + a + ",b=" + b + ",sum=" + sum);
运行结果是:a=10,b=11,sum=21

int a = 10;
int b = 10;
int sum = a+++b;
System.out.println("a=" + a + ",b=" + b + ",sum=" + sum);
运行结果是:a=11,b=10,sum=20


n=10;
m=~n;
变量n的二进制数形式:                 00000000 00000000 00000000 00001010
逐位取反后,等于十进制的-11: 11111111 11111111 11111111 11110101 


二、算术运算符
所谓算术运算符,就是数学中的加、减、乘、除等运算。因算术运算符是运算两个操作符,故又称为二元运算符。
运算符含义例子+加法运算x+y-减法运算x-y*乘法运算x*y/除法运算x/y%取模运算(求余运算)x%y

这些操作可以对不同类型的数字进行混合运算,为了保证操作的精度,系统在运算过程中会做相应的转化。数字精度的问题,我们在这里不再讨论。下图中展示了运算过程中,数据自动向上造型的原则。
  
 注:
1、实线箭头表示没有信息丢失的转换,也就是安全性的转换,虚线的箭头表示有精度损失的转化,也就是不安全的。
2、当两个操作数类型不相同时,操作数在运算前会自动向上造型成相同的类型,再进行运算。

示例如下:
 
private static void binaryOperation() {int a = 22;int b = 5;double c = 5;System.out.println(b + "+" + c + "=" + (b + c));System.out.println(b + "-" + c + "=" + (b - c));System.out.println(b + "*" + c + "=" + (b * c));System.out.println(a + "/" + b + "=" + (a / b));System.out.println(a + "%" + b + "=" + (a % b));System.out.println(a + "/" + c + "=" + (a / c));System.out.println(a + "%" + c + "=" + (a % c));}
【运行结果】
5+5.0=10.0
5-5.0=0.0
5*5.0=25.0
22/5=4
22%5=2
22/5.0=4.4
22%5.0=2.0

三、移位运算符

移位运算符操作的对象就是二进制的位,可以单独用移位运算符来处理int型整数。

运算符含义例子<<左移运算符,将运算符左边的对象向左移动运算符右边指定的位数(在低位补0)x<<3>>"有符号"右移运算 符,将运算符左边的对象向右移动运算符右边指定的位数。使用符号扩展机制,也就是说,如果值为正,则在高位补0,如果值为负,则在高位补1.x>>3>>>"无符号"右移运算 符,将运算符左边的对象向右移动运算符右边指定的位数。采用0扩展机制,也就是说,无论值的正负,都在高位补0.x>>>3

1.左移运算符(<<)
左移运算符是用来将一个数的二进制数位左移若干位,移动的位数由右操作数指定(右操作数必须是非负值),其右边空出的位用 0 填补,高位左移溢出则舍弃该高位。

  如:5 << 2;
⑴.先将 5 转换为二进制数据为:00000000 00000000 00000000 00000101
⑵.将 101 左移 2 位后为:00000000 00000000 00000000 00010100
⑶.再将 10100 转换为 10 进制为:20

  最后计算出 5 << 2 的结果为 20。

2."有符号"右移动运算符(>>)

右移运算符是用来将一个数的二进制数位右移若干位,移动的位数由右操作数指定(右操作数必须是非负值),使用符号扩展机制,也就是说,如果值为正,则在高位补 0,如果值为负,则在高位补 1。

  如:5 >> 2;
⑴.先将 5 转换为二进制数据为:00000000 00000000 00000000 00000101
⑵.将 101 右移 2 位后为:00000000 00000000 00000000 00000001
⑶.再将 1 转换为 10 进制为:1

  最后计算出 5 >> 2 的结果为 1。

3."无符号"右移动运算符(>>>)

右移运算符是用来将一个数的二进制数位右移若干位,移动的位数由右操作数指定(右操作数必须是非负值),采用 0 扩展机制,也就是说,无论值的正负,都在高位补 0,即最终结果为正数。

  如:-5 >>> 2;
⑴.先将 -5 转换为二进制数据为:11111111 11111111 11111111 11111011
⑵.将 11111111 11111111 11111111 11111011 右移 2 位后为:00111111 11111111 11111111 11111110
⑶.再将 00111111 11111111 11111111 11111110 转换为 10 进制为:1073741822

  最后计算出 -5 >>> 2 的结果为 11073741822。

注:
x<<y 相当于 x*2y ;x>>y相当于x/2y
从计算速度上讲,移位运算要比算术运算快。
如果 x 是负数,那么 x>>>3 没有什么算术意义,只有逻辑意义。


四、关系运算符

Java 具有完备的关系运算符,这些关系运算符同数学中的关系运算符是一致的。具体说明如下:
运算符含义例子<小于x<y>大于x>y<=小于等于x<=y>=大于等于x>=y==等于x==y!=不等于x!=y

instanceof 操作符用于判断一个引用类型所引用的对象是否是一个类的实例。操作符左边的操作元是一个引用类型,右边的操作元是一个类名或者接口,形式如下:

obj instanceof ClassName 或者 obj instanceof InterfaceName

private static void inOf() {String s = "I AM an Object!";boolean isObject = s instanceof Object;System.out.println(isObject);}

【运行结果】
true


关系运算符产生的结果都是布尔型的值,一般情况下,在逻辑与控制中会经常使用关系运算符,用于选择控制的分支,实现逻辑要求。

需要注意的是:关系运算符中的"=="和"!="既可以操作基本数据类型,也可以操作引用数据类型。操作引用数据类型时,比较的是引用的内存地址。所以在比较非基本数据类型时,应该使用 equals 方法。


五、逻辑运算符

逻辑非关系值表

A!Atruefalse

false

true

 
逻辑与关系值表
ABA&&Bfalsefalsefalsetruefalsefalsefalsetruefalsetruetruetrue
 
逻辑或关系值表
ABA||Bfalsefalsefalsetruefalsetruefalsetrue   true truetruetrue 
在运用逻辑运算符进行相关的操作,就不得不说“短路”现象。代码如下:


if (1 == 1 && 1 == 2 && 1 == 3) {
}


代码从左至右执行,执行第一个逻辑表达式后:true && 1==2 && 1==3
执行第二个逻辑表达式后:true && false && 1==3
因为其中有一个表达式的值是 false,可以判定整个表达式的值是 false,就没有必要执行第三个表达式了,所以 java 虚拟机不执行 1==3 代码,就好像被短路掉了。

逻辑或也存在“短路”现象,当执行到有一个表达式的值为 true 时,整个表达式的值就为 true,后面的代码就不执行了。

“短路”现象在多重判断和逻辑处理中非常有用。我们经常这样使用:
public void a(String str) {if (str != null && str.trim().length() > 0) {}}
如果 str 为 null,那么执行 str.trim().length() 就会报错,短路现象保证了我们的代码能够正确执行。


在书写布尔表达式时,首先处理主要条件,如果主要条件已经不满足,其他条件也就失去了处理的意义。也提高了代码的执行效率。

位运算是对整数的二进制位进行相关操作,详细运算如下:


非位运算值表
A~A10

  0 

1

与位运算值表
ABA&B111100010000


或位运算值表
ABA | B111101011000


异或位运算值表
ABA&B110101011000


示例如下:
private static void test01() {int a = 15;int b = 2;System.out.println(a + "&" + b + "=" + (a & b));System.out.println(a + "|" + b + "=" + (a | b));System.out.println(a + "^" + b + "=" + (a ^ b));}
【运行结果】
15&2=2
15|2=15
15^2=13

程序分析:
a111115b00102a&b00102a|b111115a^b110113
按位运算属于计算机低级的运算,现在我们也不频繁的进行这样的低级运算了。

六、三目运算符

三目运算符是一个特殊的运算符,它的语法形式如下:

布尔表达式?表达式1:表达式2

运算过程:如果布尔表达式的值为 true,就返回表达式 1 的值,否则返回表达式 2 的值,例如:


int sum = 90;
String str = sum < 100 ? "失败" : "成功";


等价于下列代码:

String str = null;

if (num < 100) {
str = "失败";
} else {
str = "成功";
}


三目运算符和 if……else 语句相比,前者使程序代码更加简洁。


七、赋值运算符

赋值运算符是程序中最常用的运算符了,示例如下:
运算符例子含义+=x+=yx=x+y-=x-=yx=x-y*=x*=yx=x*y/=x/=yx=x/y%=x%=yx=x%y>>=x>>=yx=x>>y>>>=a>>>=yx=x>>>y<<=a<<=yx=x<<y&=x&=yx=x&y|=x|=yx=x|y^=x^=yx=x^y
大家可以根据自己的喜好选择合适的运算符。

补充:
字符串运算符:+ 可以连接不同的字符串。
转型运算符:() 可以将一种类型的数据或对象,强制转变成另一种类型。如果类型不相容,会报异常出来。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 脚被钢钉扎了怎么办 皮帘子有胶了怎么办 12v插口没有电怎么办 吃了一颗聚乙烯醇怎么办 立式注塑机产品粘膜怎么办 被小松鼠咬了怎么办 被宠物松鼠咬了怎么办 手被松鼠咬出血怎么办 银联认证码失败怎么办 国际汇款触发合规查询怎么办 外面的网线断了怎么办 网线被别的车挂断了怎么办 施工挖断军用光缆怎么办 不小心挖断光缆怎么办 家里的光纤断了怎么办 车被树枝刮花了怎么办 货车撞断了树枝怎么办? 把光缆挖断了怎么办 光缆有外伤断了怎么办 不小心挖断移动光缆怎么办 派克服内胆掉毛怎么办 汉王电纸书怎么无法开机怎么办? 压力喷水壶坏了怎么办 行车记录仪后摄像头不清楚怎么办 蓝牙听歌声音小怎么办 对讲机时灵时不灵怎么办 黑凉粉煮稀了怎么办 轮速传感器坏了怎么办 黑魂3被入侵了怎么办 轮胎螺丝滑牙了怎么办 gta5ol寻宝任务退出了怎么办 gta5线上模式买房子之后怎么办 开摩托车忘记带安全头盔怎么办 gta不想要车了怎么办 空气滤芯进水会怎么办 车胎扎了个钉子怎么办 德罗索没导弹了怎么办 CF手雷包不能用怎么办 cfAK爆头碰到狙怎么办 玩cf网络延迟高怎么办 逆水寒装备分解错了怎么办