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;
	}

}

运算结果如下:

java operate java operater_java

位运算符(顾名思义,对操作数的位进行运算)

  1. 按位与 & :注意也是逻辑与,可以进行false,true的连接运算,同true为true
  2. 按位或 | :注意也是逻辑或,可以进行false,true的连接运算,同false为false
  3. 按位异或 ^ :
  4. 右移运算符 >> :
  5. 左移运算符 << :
  6. 无符号右移运算符 >>> :
  • 首先来看&、| 的一段测试代码:
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));
}

运算结果如下:

java operate java operater_System_02

  • 下面讨论左移、右移以及无符号右移运算符,请看代码,其中包含运算过程的具体分析:
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
	}
}

输出结果如下:

java operate java operater_java operate_03

运算时的自动类型提升问题

两个操作数进行运算会有自动类型提升问题:
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();		
}