005-Java运算符

目录

算术运算符

关系运算符

逻辑运算符

位运算(只做了解即可,能通过位运算规律进行简单的计算即可)

源码、补码、反码的概念

位运算(~、&、|、^)

位移

位运算技巧

位移

按位于 &

按位异或 ^

赋值运算符

运算符的优先级

运算规律

常见运算问题

运算规律常见运算问题


算术运算符

  • 加( + )
  • 减( - )
  • 乘( * )
  • 除( / )
  • 取余/取模( % )
  • 自增 ( ++ )
  • 自减 ( -- )
int a = 3;
int b = 5;

System.out.println(a + b);// 8
System.out.println(a - b);// -2
System.out.println(a * b);// 15
System.out.println(a / b);// 0,注意不是0.6
// 整型不能表示小数,且最后的值只截断小数位而不是四舍五入所以值是0
System.out.println(a % b);// 3

System.out.println(a++);// 3,后置自增,a++的值等于a原来的值
System.out.println(a);// 4,a++自增后a的值为a+1
System.out.println(++a);// 5,前置自增,++a的是等于a+1

System.out.println(b--);// 5,后置自减,b--的值等于b原来的值
System.out.println(b);// 4,b--后b的值为b-1
System.out.println(--b);// 3,前置自减,--b的值等于b-1

注:把a++看成一个整体,就能更好的理解a++的值为什么是等于a的原值了

  • 关于变量的自增与自减运算
    • a++;a = a +1; a += 1;这三种方法效果一样
    • 关于int b = a++,作用是将a的值先赋给b,然后再让a自增1.
    • 关于int b = ++a,作用是将a的值先自增1,然后将自增后的结果赋给 b.

关系运算符

  • 大于(>)
  • 小于(<)
  • 等于(==)
  • 不等于(!=)
  • 大于等于(>=)
  • 小于等于(<=)
  • 三元表达式 (a?b:c) :a < b?a:b;如果a < b则返回a,否则返回b

关系运算的结果是个 boolean值. 

int a = 3;
int b = 5;

System.out.println(a > b);// false
System.out.println(a < b);// true
System.out.println(a == b);// false
System.out.println(a >= b);// false
System.out.println(a <= b);// true
System.out.println(a != b);// true
System.out.println(a < b ? a:b);//返回a的值3

逻辑运算符

  • 重点讲解两个,逻辑运算符本身也返回一个boolean值
    • 逻辑与:使用&&表示,逻辑与是个双目运算符(即有两个操作数的运算符),只有 当两个操作数都为真的时候,结果才为真;其余情况结果均为假。逻辑与表示的并 且的意思
    • 逻辑或:使用||表示,逻辑或也是个双目运算符,只有当两个操作数都为假的时候, 结果才为假;其余情况结果均为真。逻辑或表示或者的意思
    • 非:使用!表示,用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。
  • 关于逻辑运算符的短路特性
    • 逻辑与:如果第一个操作数为 false,那么结果肯定就是 false,所以在这种情况下, 将不会执行逻辑与后面的运算了,即发生了短路
    • 逻辑或:如果第一个操作数为 true,那么结果肯定就是 true,所在在这种情况下, 将不会执行逻辑或后面的运算了,即发生了短路
boolean a = true;
boolean b = false;
System.out.println(a && b);// false
System.out.println(a || b);// true
System.out.println(!(a && b));// true

// 短路特性
int c = 1;
int d = 2;

System.out.println(c++ < d++ && c-- == d--);// false
System.out.println(c);// 1
System.out.println(d);// 2 因为两个条件表达式都执行了一次++一次--

System.out.println(c++ > d++ && c-- == d--);// false
System.out.println(c);// 2
System.out.println(d);// 3 因为只有第一个表单式执行了第二个表达式由于短路特性没有执行

位运算(只做了解即可,能通过位运算规律进行简单的计算即可)

源码、补码、反码的概念

要理解位运算必须先明白二进制数在内存中的存放形式,二进制数在内存中是以补码的形式存放的。

  • 源码:就是数字的二进制表示。数字130的源码为:1000 0010
  • 补码:就是二进制表示前面加一位符号位:正数符号位为0,负数符号位为1。
    • 正数的补码:正数的补码,反码都是其本身加上符号位。数字130的反码为:0 1000 0010
    • 负数的补码:符号位不变,其余各位求反,末位加1。数字-1的二进制表示为10001,补码为:11111
  • 反码
    • 正数的反码:正数的补码,反码都是其本身加上符号位。数字130的反码为:0 1000 0010
    • 负数的反码:符号位为1,其余各位求反,但末位不加1。数字-1的二进制表示为10001,反码为:11110

位运算(~、&、|、^)

/**
数字5:
源码:0000 0000 0000 0000 0000 0000 0000 0101
补码:0 0000 0000 0000 0000 0000 0000 0000 0101
反码:0 0000 0000 0000 0000 0000 0000 0000 0101
 
 
数字 -3:
源码:0000 0000 0000 0000 0000 0000 0000 0011
补码:1 1111 1111 1111 1111 1111 1111 1111 1101
反码:1 1111 1111 1111 1111 1111 1111 1111 1100
*/
=================================================================
 
~:取反运算,对补码取反,然后转换为源码输出
~5:
0 0000 0000 0000 0000 0000 0000 0000 0101   5的补码
------------------------------------------
1 1111 1111 1111 1111 1111 1111 1111 1010   补码取反
1 0000 0000 0000 0000 0000 0000 0000 0110   负数:补码转换为源码,末位减1,符号位之外各位取反
------------------------------------------
1 0000 0000 0000 0000 0000 0000 0000 0110   源码表示
------------------------------------------
-6  十进制
___________________________________________
 
 
~-3
1 1111 1111 1111 1111 1111 1111 1111 1101   -3的补码
------------------------------------------
0 0000 0000 0000 0000 0000 0000 0000 0010   补码取反
0 0000 0000 0000 0000 0000 0000 0000 0010   整数:补码转换为源码,补码 == 源码 + 符号位
------------------------------------------
0 0000 0000 0000 0000 0000 0000 0000 0010   源码表示
------------------------------------------
2   十进制
___________________________________________
 
 
/**
取反规律: ~x = -(x + 1)
*/
 
=================================================================
 
&:按位与,两个整数对应位是1结果才是1,否则是0
 
5 & -3
0 0000 0000 0000 0000 0000 0000 0000 0101   5的补码
1 1111 1111 1111 1111 1111 1111 1111 1101   -3的补码
------------------------------------------
0 0000 0000 0000 0000 0000 0000 0000 0101   5 & -3的补码
------------------------------------------
0 0000 0000 0000 0000 0000 0000 0000 0101   整数:补码转换为源码,补码 == 源码 + 符号位
------------------------------------------
0 0000 0000 0000 0000 0000 0000 0000 0101   源码表示
------------------------------------------
5   十进制
__________________________________________
 
/**
* x & 1 = 0;表示x是偶数<br>* x & 1 = 1;表示x是奇数
*/
=================================================================
 
|:按位或,两个整数对应位是0结果才是0,否则是1
 
5 | -3
0 0000 0000 0000 0000 0000 0000 0000 0101   5的补码
1 1111 1111 1111 1111 1111 1111 1111 1101   -3的补码
------------------------------------------
1 1111 1111 1111 1111 1111 1111 1111 1101   5 | -3的补码
------------------------------------------
1 0000 0000 0000 0000 0000 0000 0000 0011   负数:补码转换为源码,末位减1,符号位之外各位取反
------------------------------------------
1 0000 0000 0000 0000 0000 0000 0000 0011   源码表示
------------------------------------------
-3  十进制
__________________________________________
 
=================================================================
 
^:异或,两个整数对应位同时是0或同时是1是结果为0,否则为1
 
5 ^ -3
 
5 ^ -3
0 0000 0000 0000 0000 0000 0000 0000 0101   5的补码
1 1111 1111 1111 1111 1111 1111 1111 1101   -3的补码
------------------------------------------
1 1111 1111 1111 1111 1111 1111 1111 1000   5 ^ -3的补码
------------------------------------------
1 0000 0000 0000 0000 0000 0000 0000 1000   负数:补码转换为源码,末位减1,符号位之外各位取反
------------------------------------------
1 0000 0000 0000 0000 0000 0000 0000 1000   源码表示
------------------------------------------
-8  十进制
__________________________________________
 
/**
异或规律:
x ^ x = 0;
x ^ 0 = x;
*/

位移

  • <<:左移运算符,num << x,表示num左移x位,就是将num的补码(在内存中的二进制表示)左移x位,移出的部分去掉,右边补x个0。等价于num乘以2的x次方。
  • >>:右移运算符,num >> x,表示num右移x位,就是将num的补码,右移x位,移出的部分去掉,在左边补上x个最高位的数(最高位是0则补0。最高位为1则补1)。相当于num除以2的x次方(注意这里只有结果为整数时成立)
  • >>>:无符号右移,忽略符号位,空位都以0补齐
/**
数字5:
源码:0000 0000 0000 0000 0000 0000 0000 0101
补码:0 0000 0000 0000 0000 0000 0000 0000 0101
反码:0 0000 0000 0000 0000 0000 0000 0000 0101
 
 
数字 -3:
源码:0000 0000 0000 0000 0000 0000 0000 0011
补码:1 1111 1111 1111 1111 1111 1111 1111 1101
反码:1 1111 1111 1111 1111 1111 1111 1111 1100
*/
 
5 << 3
补码:0 0000 0000 0000 0000 0000 0000 0000 0101
左移3位: x xx00 0000 0000 0000 0000 0000 0000 0101 x表示移出的位数
移出的部分在右边补0
00 0000 0000 0000 0000 0000 0000 0101 000  后3个0是补的
转换为源码输出
00 0000 0000 0000 0000 0000 0000 0101 000
 
结果是 2^3 + 2^5 = 40  等价于 5 * 2^3 = 40
 
 
-3 << 3
补码:1 1111 1111 1111 1111 1111 1111 1111 1101
左移3位: x xx11 1111 1111 1111 1111 1111 1111 1101 x表示移出的位数
移出的部分在右边补0
11 1111 1111 1111 1111 1111 1111 1101 000  后3个0是补的
转换为源码输出
先减1:
11 1111 1111 1111 1111 1111 1111 1100 111
10 0000 0000 0000 0000 0000 0000 0011 000
 
结果是 2^3 + 2^4 = -24  等价于 -3 * 2^3 = -24
 
 
5 >> 2
补码:0 0000 0000 0000 0000 0000 0000 0000 0101
右移两位:0 0000 0000 0000 0000 0000 0000 0000 01xx  x表示移出的位数
移出的部分在左边补最高位的0
000 0000 0000 0000 0000 0000 0000 0000 01        前两个0是补的
转换为源码输出
000 0000 0000 0000 0000 0000 0000 0000 01
结果为 1  等价于 5 / 2^2 = 1(此不能整除,但结果正确)
 
 
-3 >> 1
补码:1 1111 1111 1111 1111 1111 1111 1111 1101
右移一位:1 1111 1111 1111 1111 1111 1111 1111 110x  x表示移出的位数
移出的部分在左边补最高位的1
11 1111 1111 1111 1111 1111 1111 1111 110            第一个1是补的
转换为源码输出
补码-1
11 1111 1111 1111 1111 1111 1111 1111 101
取反
10 0000 0000 0000 0000 0000 0000 0000 010
结果为 -2  此结果不符合运算规律(因为-3/2不能整除)
 
 
5 >>> 2
补码:0 0000 0000 0000 0000 0000 0000 0000 0101
无符号右移2位:
0 0000 0000 0000 0000 0000 0000 0000 01xx  x表示移出的位数
移出的部分在左边补0(无论最高位是多少)
000 0000 0000 0000 0000 0000 0000 0000 01        前两个0是补的
转换为源码输出
000 0000 0000 0000 0000 0000 0000 0000 01
结果为 1  等价于 5 / 2^2 = 1(此不能整除,但结果正确)
此结果说明,正数的右移与其无符号右移结果相同
 
 
-3 >>> 1
补码:1 1111 1111 1111 1111 1111 1111 1111 1101
右移一位:1 1111 1111 1111 1111 1111 1111 1111 110x  x表示移出的位数
移出的部分在左边补0(无论最高位是多少)
01 1111 1111 1111 1111 1111 1111 1111 110            第一个0是补的
转换为源码输出
01 1111 1111 1111 1111 1111 1111 1111 110
 
结果为 2147483646

位运算技巧

位移

  • 移位运算符适用类型有byte、short、char、int、long 
  • 对低于int型的操作数将先自动转换为int型再移位。  
  • 对于int型整数移位a>>b,系统先将b对32取模,得到的结果才是真正移位的位数。例如:a>>33和a>>1结果是一样的 
  • 对于long型整数移位时a>>b ,则是先将移位位数b对64取模。
  • 移位不会改变变量本身的值。也就是a>>b后,a的值是不变的
  • x>>1的结果和x/2的结果是一样的,x<<2和x*4的结果也是一样的。总之,一个数左移n位,就是等于这个数乘以2的n次方,一个数右移n位,就是等于这个数除以2的n次方。用程序实现求2的x次方:y = 1<< x;

按位于 &

  • a&1=0偶数
  • a&1=1奇数
  • a&1等价于a%2

按位异或 ^

  • x^0=x;
  • x^x=0;
  • 两个int类型变量x、y,要求两者数字交换,位运算的实现
//使用异或来实现不新增变量实现两个变量的值的交换
int x = 3;
int y = 5;

x ^= y; 
y ^= x; 
x ^= y; 

System.out.println(x);//5
System.out.println(y);//3

赋值运算符

  • 赋值( = )
  • 加等赋值 ( += )
  • 减等赋值 ( -= )
  • 乘等赋值 ( *= )
  • 除等赋值 ( /= )
  • 模等赋值 ( %= )
  • 左移赋值 ( <<= )
  • 右移赋值( >>= )
  • 按位与赋值 ( &= )
  • 按位异或赋值( ^= )
  • 按位或赋值( |= )

运算符的优先级

优先级运算符结合性
1()、[]、{}从左向右
2!、+、-、~、++、--从右向左
3*、/、%从左向右
4+、-从左向右
5«、»、>>>从左向右
6<、<=、>、>=、instanceof从左向右
7==、!=从左向右
8&从左向右
9^从左向右
10|从左向右
11&&从左向右
12||从左向右
13?:从右向左
14=、+=、-=、*=、/=、&=、|=、^=、~=、«=、»=、>>>=从右向左

运算规律

  • 1. 当有若干个变量参与运算时,结果类型取决于这些变量中表示范围最大的那个变量类型。 比如,参与运算的变量中,有整型 int,有双精度浮点型 double,有短整型 short,那么 最后的结果类型就是 double
  • 2. 取模的规律:取模的结果符号永远与被除数的符号相同
// 数字类型参与运算,最后的结果的类等于表示范围最广的类型
System.out.println( (10 + 5.0) / 20 );//-- 0.75
 
//-- 取模(取余)
System.out.println( (20 + 5.3) % 20 );//-- 5.300000000000001
//-- 浮点型就有5.300000000000001和数学运算有些出入
//在银行业务系统或大额支付等系统中或者涉及精确计算时不要使用浮点型进行计算。
//java有提供专门的精确计算的类来进行精确计算

常见运算问题

  • 除法:int a = 1;int b = 2; a/b的值为0;而不是0.5;(double)a/b = 0.5 上面的代码中,a与 b都是整型,但是通过(double)a这种转换将a转换为一个匿名的变 量,该变量的类型是 double,但是要注意:a本身依旧是 int类型,而不是double类型, 这样,(double)a / b就是 double类型除以 int类型,结果自然是double类型。
  • 取模运算符--使用%表示:
    • int a = 5;int b = 3; a%b = 2
    • int a = -5;int b = 3; a%b = -2
    • int a = 5;int b = 3; b%a = 3
    • int a = -5;int b = 3; b%a = 3
  • 关于除数为0:
    • int a = 5;int b = 0; a/b  编译不会报错,但会报除数为0的异常ArithmeticException(运行时异常)
    • long a = 5L;long b = 0L; a/b 编译不会报错,但会报除数为0的异常ArithmeticException(运行时异常)
    • float a = 5F;float b = 0.0F; a/b=Infinity 编译以及运行都不会报错,执行结果为Infinity 
    • double a = 5;double b = 0; a/b=Infinity 编译以及运行都不会报错,执行结果为Infinity 

点击进入系列文章目录列表https://blog.csdn.net/forlinkext/category_6738598.html

上一篇:004-变量定义

下一篇:006-Java控制语句

运算规律常见运算问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值