算术运算符
+、-、*、/、%(取余)
int a =3; int b =0; b=a/2; //需注意b是整型,3/2的值是1 //------------------------------------------------------- int a = 4; int b =0; b=a%2; //a%2,求的书4/2的余数,为0
赋值运算符
= 、+=、 -=、 /=、 *=、%=
int x=1; //把1赋给变量x x+=1; //类似于:x=x+1; //-------------------------------------------------------- byte x =1; x += 2; //+=类似于=,等号右边是常数,自动类型转化 int y =1; byte b =0; y += b; //+=类似于=,等号右边是常数,自动类型转化 x = (byte)(x+2); //不加byte编译报错,类型从int转化为byte可能有损失,可以看成等于右边为一个表达式,不做自动转化
关系运算符
>、<、>=、<=、==、!=、instanceof(用于比较一个对象是否属于一个类型)
关系运算符的结果为Boolean类型
逻辑运算符
&&(短路与)、&(逻辑与)、||(短路或)、|(逻辑或)、!(非)、^(逻辑异或)
短路与与逻辑与的区别在于,当第一个条件为假时,短路与会发生短路,后面的不执行,逻辑与不论是真还是假都会执行到最后;
短路或与逻辑或的区别在于,当第一个条件为真时,短路或会发生短路,后面的不执行,逻辑或不论是真还是假都会执行到最后
短路与和短路或在发生短路的情况下,性能才比逻辑与或者逻辑或更高
(3>1)^(3<2):前后两个表达式结果不同,那么最终结果为true,反之为false
位运算符
进制转换(扩展):
十进制转二进制:除2直到商为1,将余数倒序排列
二进制转十进制:每个元素乘以2的位数-1,求和
00000100 0*27 + 0*26+0*25 + 0*24 + 0*23 + 1*22 + 0*21 +0*20 = 4
八进制:以3个bit为一组,把每一组计算成十进制,开头加上数字0,作为标记。
16进制:以4个bit为一组,把每一组用二进制转十进制的方式方式,计算每一组的数,有些不同的是,10到15的数字,分别依次用A、B、C、D、E、F表示,开头加上0x(数字0,不是字母o),作为标记。
0010 1110
2 E
16进制:0x2E
&(按位与)、 |(按位或)、^(按位异或)、~(按位取反)、<<(按位左位移)、>>(按位右位移)、>>>【按位右位移(无符号)】
按位与运算,类似于把1看成真,0看成假,只有对应bit的数都为1,该bit结果才为1,其他都为0
9 & 1 == 1
00001001
00000001
00000001
按位或运算,类似于把1看成真,0看成假,只要对应bit位上有1,该bit结果才为1,其他为0
9 | 1 == 9
00001001
00000001
00001001
按位异或,类似于把1看成真,0看成假,当对应bit位上两个数不一样,该bit结果为1,其他为0
9 ^ 1 == 8
00001001
00000001
00001000
按位取反,在这,我们需要知道计算机中无论是正数还是负数,其在内存中的存储形式都是一补码的形式存储的,其中,正数的原码、反码、补码都是一样的(下面的二进制数也可以用 符号位+有效位 来代替 ,如 9的原码----—> 01001)
9
原码:00000000 00000000 00000000 00001001
反码:00000000 00000000 00000000 00001001
补码:00000000 00000000 00000000 00001001
-9
原码:10000000 00000000 00000000 00001001
反码:11111111 11111111 11111111 11110110(符号位不变,其余取反)
补码:11111111 11111111 11111111 11110111(反码+1)
~9 == -10
9的补码: 00000000 00000000 00000000 00001001
取反: 11111111 11111111 11111111 11110110
-1(因为求的是负数的原码): 11111111 11111111 11111111 11110101
“取反后的数”的原码(符号位不变,其余取反): 10000000 00000000 00000000 00001010
看起来有点绕,可以这样认为:找到了9的补码,先将9的补码取反(可以把它看成~9),再 - 1,最后符号位不变,其余取反(后面两步类似于求一个负数的补码的逆过程,是把取反后的数,这个数可看成你要求的数的补码,将这个数的补码转成原码的形式)
负数和正数的过程也差不多
~(-9) ==8
-9的补码: 11111111 11111111 11111111 11110111
取反: 00000000 00000000 00000000 00001000
“取反后的数”的原码(正数的原码、反码、补码相同): 00000000 00000000 00000000 00001000
按位左位移
6 << 2 == 24
00000000 00000000 00000000 00000110
类似于在之前的最右边加位移个数(即上面“6 << 2 ”的2)的0(无论正数还是负数),再把最左边的位移个数的数去掉(符号位不动,即去掉符号位之后的)
00000000 00000000 00000000 00011000
也先相当于,乘以2的位移次幂,即6 * 22 = 24
-6 << 2 == -24
-6的补码: 11111111 11111111 11111111 11111010
按位左位移运算: 11111111 11111111 11111111 11101000
符号位不变,其他位,取反:11111111 11111111 11111111 00010111
+1: 1000000 0000000 0000000 00011000
按位右位移
6 >> 1 == 3
00000000 00000000 00000000 00000110(6的补码)
类似于在之前的最右边减掉位移个数(即2)的0或1,在最左边加上位移个数的数的0(正数)或1(负数)(符号位不动,即类似于在符号位后加)
00000000 00000000 00000000 00000011
也先相当于,除以2的位移次幂,即6 / 21 = 3
-6 >> 1 == -3
-6的补码: 11111111 11111111 11111111 11111010
按位右位移运算: 11111111 11111111 11111111 11111101
符号位不变,其他位,取反: 10000000 00000000 00000000 00000010
+1: 10000000 00000000 00000000 00000011
所以,我们再做一些乘除法运算时,可以利用这些来做,提高计算机的计算效率
-6 >>> 1 == 2147483654
11111111 11111111 11111111 11111010(-6的补码)
类似于在之前的最右边砍掉位移个数的0或1(不考虑符号位,无论正数还是负数都直接在最左边补0)
011111111 11111111 11111111 1111101
注意:
位运算是用补码来进行的,正数的三码都一样,负数的三码是有区别,在&、|、~、<<、>>、>>>,中如果是负数的位运算,需要注意这一点