一、运算符

1、算数运算符

+ - * / %(取余数)

2、比较运算符

  • > < <= >= == !=
  • “==” 基本类型比较的是其值是否相等

例如short a = 2; int b = 2; a==b 结果为true
用于比较,表达式结果为boolean的逻辑值

3、逻辑运算符

  • 计算的都是逻辑值true false
  • 符号:& && | || ! ^(异或,相同为假,不同为真)

真值表



&

|

true

true

T

T

true

false

F

T

false

true

F

T

false

false

F

F

短路与:&& 短路或:||(如果第一个式子的结果可以判断整个逻辑表达式的结果,则不判断后面的式子)

public class TestOperator{
    public static void main(String[] args){
        int a = 12;
        int b = 21;
        int c = 21;
        // 测试短路与与普通与的区别,短路或的原理一样
        boolean bool = a>b & a<++b;
        boolean bool2 = a>c && a<++c;
        System.out.println("bool:" + bool + "  b = " + b);
        System.out.println("bool:" + bool2 + "  c = " + c);
        }
    }//out>>>bool:false  b = 22;bool:false  c = 21

4、位运算符

将运算符化作二进制进行计算 位运算符速度相对普通类型运算要快

  • << 左移
int num = 9;//  二进制:0000 0000 0000 0000 0000 0000 0000 1001
num = 9>>1;// 左移一位:0000 0000 0000 0000 0000 0000 0001 0010
  • >> 右移
int num = 9;//  二进制:0000 0000 0000 0000 0000 0000 0000 1001
num = 9>>1;// 右移一位:0000 0000 0000 0000 0000 0000 0000 0100

正数右移补位用0,负数右移补位用1

int num = -9;
num = (-9>>1);//右移一位
// 1000 0000 0000 0000 0000 0000 0000 1001 源码
// 1111 1111 1111 1111 1111 1111 1111 0111 补码
// 1111 1111 1111 1111 1111 1111 1111 1011 负数右移一位,补1
// 1000 0000 0000 0000 0000 0000 0000 0101 最终结果-3
  • >>> 无符号右移
    *计算机中存储的是二进制的补码:正数的补码就是源码,负数的补码是其源码取反加1;
    只对32位与64位的值有意义;
    byte,short,char类型进行移位操作时会自动转换为int类型;
    无符号右移,无论是负数还是正数 高位补0*
byte byte1 = -32;
System.out.println("-32无符号右移1位:" + (byte1>>>1));
//out>>>-32无符号右移1位:2147483632
// 1000 0000 0000 0000 0000 0000 0010 0000 源码
// 1111 1111 1111 1111 1111 1111 1110 0000 补码
// 0111 1111 1111 1111 1111 1111 1111 0000 = 2147483632 无符号右移一位(最终结果)
  • & 按位与
  • | 按位或
  • ~ 非
  • ^ 按位异或(相同为0,不同为1)
    异或可以用来:判断两个操作数是否同号,交换两个数
int f = 1;
int g = 2;
f = f ^ g;
g = f ^ g;
f = f ^ g;
System.out.println("f = " + f + ", g = " + g);
//out>>>f = 2, g = 1 不需要中间引入中间变量就可以交换两个数值

5、扩展运算符

所有双目运算符和等= 相结合就形成了扩展运算

  • += -= *= /= %=
  • >>= <<= >>>=

注意:a = a + b; ~ a += b ==> a = (a的类型)(a+b)

byte c = 1;
int  d = 2;
//c = c + d; 会有转换精度损失错误
c += d; // 不会报错 相当于c = (byte)(c+d)
System.out.println(c);

6、单目运算符

  • ++(自增运算)
  • –(自减运算)
public class SingleOperator{
    public static void main(String[] args){
        int a = 10;
        System.out.println((a++) + (++a));// 22
        // ++ -- 在操作数前是先计算后使用, 在操作数后是先使用后计算
        int b = 9;
        System.out.println("b++的值为:" + b++);// 9
        System.out.println("b的值为:" + b);//10 使用后就加了一了变为了10
    }
}//out>>>22; b++的值为:9; b的值为:10

二、思考题:

1、 为什么输出的结果不是28.26,而是有点精度损失?

double pi = 3.14;
int r = 3;
System.out.println(pi*r*r);
//结果为:28.25999999998

解析:
为何浮点数可能丢失精度浮点十进制值通常没有完全相同的二进制表示形式。 这是 CPU 所采用的浮点数据表示形式的副作用。为此,可能会经历一些精度丢失,并且一些浮点运算可能会产生意外的结果。
导致此行为的原因是下面之一:
1. 十进制数的二进制表示形式可能不精确
2. 使用的数字之间类型不匹配(例如,混合使用浮点型和双精度型)

2、Java中为什么1加1等于2?

解析:
0000 0000 0000 0000 0000 0000 0000 0001
0000 0000 0000 0000 0000 0000 0000 0001
0000 0000 0000 0000 0000 0000 0000 0010