java基础回顾--运算符operator
- java支持的运算符operator
- 取模运算符
- 自增、自减运算符
- 位运算符(顾名思义,对操作数的位进行运算)
- 运算时的自动类型提升问题
- 1. 整数运算
- 2. 浮点运算
java支持的运算符operator
- 算术运算符:+,-,*,/,%,++,–
- 赋值运算符:=
- 关系运算符:>,<,>=,<=,==,!=,instanceof
- 逻辑运算符:&(逻辑与),|(逻辑或),!(逻辑非), &&(短路与),||(短路或)(采用短路的方式,从左到右计算,如果第一个操作数已经能够确定表达是你的值,第二个操作数就不必计算了)
- 位运算符:&(按位与),|(按位或),^(按位异或),~(取反),>>(右移),<<(左移),>>>(无符号右移运算符)
- 条件运算符: a?b:c
- 扩展赋值运算符:+=,-=,*=,/=
算术、赋值、逻辑、扩展赋值以及条件运算符相对简单,在此不过多介绍。
取模运算符
- 整数被0除会产生一个异常,浮点数被0除会得到无穷大或NaN结果。
- 结果的正负与被除数保持一致:
(1)正数%正数 = 正数;
(2)负数%负数=负数;
(3)负数%正数=负数;
(4)正数%负数=正数;
float f2 = 4.0f; //定义单精度浮点数
double d = -0.3; //定义双精度浮点数
System.out.println(f2%d); //结果为负数
自增、自减运算符
public class AutoAdd {
public static void main(String[] args) {
// TODO Auto-geierated method stub
int i=7;int m=7;
System.out.println("i++:"+(i++)+"\ni++在运算时使用原值7,之后再加1\n");
System.out.println("使用i++之后的i值:"+i+"\n");
System.out.println("++i:"+(++i)); //先+1再参与运算等处理
int k;
k=m++ + ++m;
System.out.println("k=m++ + ++m;\nk的值为:"+k); //k=(i++)+(++i)=7+9=16;
}
}
运算结果如下:
位运算符(顾名思义,对操作数的位进行运算)
- 按位与 & :注意也是逻辑与,可以进行false,true的连接运算,同true为true
- 按位或 | :注意也是逻辑或,可以进行false,true的连接运算,同false为false
- 按位异或 ^ :
- 右移运算符 >> :
- 左移运算符 << :
- 无符号右移运算符 >>> :
- 首先来看&、| 的一段测试代码:
public static void main(String[] args) {
//测试 &、| 作为逻辑运算符和位运算符的不同表现
int x = 1;
int y = 1;
if(x++==2 & ++y==2){
System.out.println("&逻辑运算 结果为true");
}else if(x++==2 | ++y==2){
System.out.println("|逻辑运算 结果为true");
}
System.out.println("此时的x:"+x+",y:"+y);
x=1; //注意此时x重新设置为1
System.out.println("x|y:"+(x|y));
System.out.println("x&y:"+(x&y));
}
运算结果如下:
- 下面讨论左移、右移以及无符号右移运算符,请看代码,其中包含运算过程的具体分析:
public class WeiYunSuan {
public static void main(String[] args) {
// 二进制中符号位0代表正数,1代表负数,本质上移位运算符是移动存储在计算机上的二进制存储
// 正数的反码是其本身,负数的反码是在其原码的基础上,符号位不变,其余各个位取反;正数的补码是其本身,负数的补码是在反码的基础上+1
// <<:左移运算符,左移一位相当于乘2,左移直接移,不用特意管符号位
// >>:右移运算符,正数右移一位相当于除2取商,位运算时正数右移几位之后,符号位用0补齐,
// 负数需要先计算反码、补码,然后补码右移几位(全部右移,在补码处符号位也要移动),
// 移动完成后,符号位补1,得出移动后的结果数的补码,再求回原码(补码-1,取反)
// >>>:无符号右移运算符,忽略符号位,意思是也要移动符号位,最左边不管正负数一律以0补齐,
// 注意正数的无符号右移与有符号右移结果一样,因为移动一样的位数,同时又都在高位补0
System.out.println("测试左移运算符:");
int b=1<<3,b1=-1<<3; //左移三位,1*2*2*2=8,-1*2*2*2=-8
System.out.println("b="+b+",b1="+b1); //结果为8,-8
我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======
我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======
System.out.println("\n测试右移运算符:");
int c=-3>>1;
// 原码 1 000 0011
// 反码 1 111 1100
// 补码 1 111 1101
// 右移补码 1 111 1110
// 反码 1 111 1101
// 原码 1 000 0010
int c1=3>>1;
//原反补码 0 000 0011
// 移位后 0 000 0001
System.out.println("c="+c+",c1="+c1); //结果为-2,1
System.out.println("c的二进制表示:"+Integer.toBinaryString(c)
+"\nc1的二进制表示:"+Integer.toBinaryString(c1)); //二进制高位(左边)的0会自动省略
//我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======
//我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======我是分割线======
System.out.println("\n测试无符号右移运算符:");
int f=-3>>>1;
// 实际上是32位存储起来的
//负数补码 11111111 11111111 11111111 11111101
// 移动后 01111111 11111111 11111111 11111110(注意符号位为0,代表正数,正数的原码、反码和补码是一样的)
//结果反码 01111111 11111111 11111111 11111110
//结果原码 01111111 11111111 11111111 11111110
int f1=1>>>1; int f2=5>>>1;
int f11=1>>1; int f22=5>>1;
System.out.println("f="+f); //结果为2147483646
System.out.println("f1="+f1+",f11="+f11+"\nf2="+f2+",f22="+f22); //结果为0,0 换行 2,2
}
}
输出结果如下:
运算时的自动类型提升问题
两个操作数进行运算会有自动类型提升问题:
byte、short、char --> int --> long --> float --> double( float范围大于long )
1. 整数运算
- 如果两个操作数有一个为Long,则结果也为Long。
- 没有Long时,结果为int。即使操作数全为short,byte,char,结果也是int。
- 有float时,byte,short,char,int,l结果都为float。
//示例代码如下:
public static void main(String[] args) {
int a = 12;
long l = 1L;
short s = 2;
byte b = 5;
byte b1 = 3;
//byte b2 = b1 + b;这样写是错误的,因为自动类型提升,结果已经是int型,int型转变成byte,需要强制类型转换
byte b2 = (byte)(b+b1);
System.out.println(getType(a+l)); //类型是long
System.out.println(getType(s+b)); //类型是int
}
//打印数据类型方法
public static String getType(Object test) {
return test.getClass().getName().toString();
}
2. 浮点运算
如果两个操作数有一个为double,,则结果为double。
只有两个操作数都是float,则结果才为float。
//示例代码如下:
public static void main(String[] args) {
float f0 = 1f, f1 = 2.0f;
double d0 = 12.0, d1 = 7;;
System.out.println(getType(f0+f1)); //类型是float
System.out.println(getType(f0+d0)); //类型是double
System.out.println(getType(d0+d1)); //类型是double
}
//打印数据类型方法
public static String getType(Object test) {
return test.getClass().getName().toString();
}