1. 数学运算符
概念:
- 基本运算:包括加(
+),减(-),乘(*),除(/)。- 除法运算中,如果操作数都是整数,则结果也是整数。
- 取余运算:取余运算符(
%),0取余任何数都等于0,正负号只和等号左边操作数的一致。 - 除零问题:任何数除以0都会抛异常,任何数除以0.0结果都为无穷大
infinity。
源码: /javase-start/
- src:
c.y.calculation.MathOperatorsTest.base()
/**
* @author yap
*/
public class MathOperatorsTest {
@Test
public void base() {
System.out.println(0 % 2);
System.out.println(5 % 2);
System.out.println(5 % -2);
System.out.println(-5 % 2);
System.out.println(-5 % -2);
System.out.println(1 / 0.0);
System.out.println(1 / 0);
}
}
1.1 自运算
概念:
- 自运算
++/--即给自身加1或减1。 - 自运算优先级最高。
- 自运算只能用在变量上,常量没有自运算。
- 自运算分为先用后加(a++)和先加后用(++a);
1.2 数值溢出问题
概念:
- 我们都知道变量是有自己的存值范围的,比如 byte 的存值范围是-128 ~ 127之间,那么假设在计算的时候发生了数值溢出,会产生物极必反的现象:
- 最大值加1变成最小值
- 最小值减1变成最大值
- 二进制计算的原理:将原码转成补码,使用补码进行计算,再将结果转回原码。
- 模拟 2147483647 + 1 的过程
- 原码: [01111111 11111111 11111111 11111111]
- 反码: [01111111 11111111 11111111 11111111],与原码相同
- 补码: [01111111 11111111 11111111 11111111],与原码相同
- 加一: [10000000 00000000 00000000 00000000],计算会影响符号位,toBinaryString()方法会打印这个值
- 反码: [11111111 11111111 11111111 11111111],符号位不动,其余按位取反
- 补码: [10000000 00000000 00000000 00000000],反码 + 1,符号位不参与补码进位
- 真值: -2147483648(int最小值)
- 模拟 -2147483648 - 1 的过程
- 原码: [10000000 00000000 00000000 00000000]
- 反码: [11111111 11111111 11111111 11111111],符号位不动,其余按位取反
- 补码: [10000000 00000000 00000000 00000000],反码 + 1,符号位不参与补码进位
- 减一: [01111111 11111111 11111111 11111111],计算会影响符号位,toBinaryString()方法会打印这个值
- 反码: [01111111 11111111 11111111 11111111],与原码相同
- 补码: [01111111 11111111 11111111 11111111],与原码相同
- 真值: 2147483647(int最大值)
源码: /javase-start/
- src:
c.y.calculation.MathOperatorsTest.numericalOverflow()
@Test
public void numericalOverflow() {
int maxValueOfInt = 2147483647;
int result = maxValueOfInt + 1;
System.out.println(result);
}
2. 赋值运算符
概念: java中使用一个等号表示赋值,赋值要从后向前理解:
+=:追加,a += b就等价于a = a+b,将a+b的结果重新赋值给a-=:追减,a -= b就等价于a = a-b,将a-b的结果重新赋值给a*=:追乘,a *= b就等价于a = a*b,将a*b的结果重新赋值给a/=:追除,a /= b就等价于a = a/b,将a/b的结果重新赋值给a%=:追取余,a %= b就等价于a = a%b,将a+b的结果重新赋值给a
3. 比较运算符
概念: 比较运算一定会返回boolean类型的值,运算符包括:== / > / < / >= / <= / !=。
4. 逻辑运算符
概念: 逻辑运算包括逻辑与(&&),逻辑或(||)和逻辑非(!)。
- 口诀:与中有假(则假),或中有真(则真)。
- 逻辑运算优先级:非 > 与 > 或。
5. 位运算符
概念: 位运算发生在操作数的补码间,对补码计算结果再次求补转回原码后可得真值:
- 短路现象:逻辑运算会发生短路现象,而位运算不会。
- 按位与
$:有0则0,全1才1。 - 按位或
|:有1则1,全0才0。 - 按位取反
~:0变1,1变0,包括符号位。 - 按位异或
^:相同为0,不同为1,等效于按位无进位相加:- 异或操作满足交换律和结合律,即a^(b^c) 等同 (c^b)^z。
- 规律:N^0=N,N^N=0。
- 左移动
<<:按位左移动时,溢出忽略,右边用0补位:- a左移动b位,相当于a乘以2的b次方。
- 带符号右移动
>>:按位带符号右移动时,溢出忽略,左边用符号位补位:- a右移动b位,相当于a除以2的b次方。
- 无符号右移动
>>>:按位无符号右移动时,溢出忽略,左边用0补位。
源码: /javase-start/
- src:
c.y.calculation.MathOperatorsTest
/**
* <h1>4 & 6 过程分析</h1>
*
* <p> 00000000 .. 00000100:4原码
* <p> 00000000 .. 00000100:取反得到4反码,同原码
* <p> 00000000 .. 00000100:加1得到4补码,同原码
* <p> 00000000 .. 00000110:6原码
* <p> 00000000 .. 00000110:取反得到6反码,同原码
* <p> 00000000 .. 00000110:加1得到6补码,同原码
* <p> 00000000 .. 00000100:4 & 6结果,有0则0
* <p> 00000000 .. 00000100:取反得到结果的反码,同原码
* <p> 00000000 .. 00000100:加1得到结果的补码,同原码
* <p> 4:真值
*/
@Test
public void andOfBit() {
System.out.println(Integer.toBinaryString(4 & 6));
System.out.println(4 & 6);
}
/**
* <h1>4 | 6 过程分析</h1>
*
* <p> 00000000 .. 00000100:4原码
* <p> 00000000 .. 00000100:取反得到4反码,同原码
* <p> 00000000 .. 00000100:加1得到4补码,同原码
* <p> 00000000 .. 00000110:6原码
* <p> 00000000 .. 00000110:取反得到6反码,同原码
* <p> 00000000 .. 00000110:加1得到6补码,同原码
* <p> 00000000 .. 00000100:4 | 6结果,有1则1
* <p> 00000000 .. 00000110:取反得到结果的反码,同原码
* <p> 00000000 .. 00000110:加1得到结果的补码,同原码
* <p> 6:真值
*/
@Test
public void orOfBit() {
System.out.println(Integer.toBinaryString(4 | 6));
System.out.println(4 | 6);
}
/**
* <h1> ~4 过程分析</h1>
*
* <p> 00000000 .. 00000100:4原码
* <p> 00000000 .. 00000100:取反得到4反码,同原码
* <p> 00000000 .. 00000100:加1得到4补码,同原码
* <p> 11111111 .. 11111011:~4结果,所有位取反,包括符号位
* <p> 10000000 .. 00000100:取反得到结果的反码
* <p> 10000000 .. 00000101:加1得到结果的补码
* <p> -5:真值
*/
@Test
public void notOfBit() {
System.out.println(Integer.toBinaryString(~4));
System.out.println(~4);
}
/**
* <h1>4 ^ 6 过程分析</h1>
*
* <p> 00000000 .. 00000100:4原码
* <p> 00000000 .. 00000100:取反得到4反码,同原码
* <p> 00000000 .. 00000100:加1得到4补码,同原码
* <p> 00000000 .. 00000110:6原码
* <p> 00000000 .. 00000110:取反得到6反码,同原码
* <p> 00000000 .. 00000110:加1得到6补码,同原码
* <p> 00000000 .. 00000010:4 ^ 6结果,无进位相加
* <p> 00000000 .. 00000010:取反得到结果的反码,同原码
* <p> 00000000 .. 00000010:加1得到结果的补码,同原码
* <p> 2:真值
*/
@Test
public void xorOfBit() {
System.out.println(Integer.toBinaryString(4 ^ 6));
System.out.println(4 ^ 6);
}
/**
* <h1>-2 << 3 过程分析</h1>
*
* <p> 10000000 .. 00000010:-2原码
* <p> 11111111 .. 11111101:取反得到-2反码
* <p> 11111111 .. 11111110:加1得到-2补码
* <p> 11111111 .. 11110000:-2 << 3结果,左移动3,溢出忽略,用0补位。
* <p> 10000000 .. 00001111:取反得到结果的反码
* <p> 10000000 .. 00010000:加1得到结果的补码
* <p> -16:真值
*/
@Test
public void leftMoveOfBit() {
System.out.println(Integer.toBinaryString(-2 << 3));
System.out.println(-2 << 3);
}
/**
* <h1>-2 >> 3 过程分析</h1>
*
* <p> 10000000 .. 00000010:-2原码
* <p> 11111111 .. 11111101:取反得到-2反码
* <p> 11111111 .. 11111110:加1得到-2补码
* <p> 11111111 .. 11111111:-2 >> 3结果,右移动3,溢出忽略,用符号位补位。
* <p> 10000000 .. 00000000:取反得到结果的反码
* <p> 10000000 .. 00000001:加1得到结果的补码
* <p> -1:真值
*/
@Test
public void rightMoveOfBit() {
System.out.println(Integer.toBinaryString(-2 >> 3));
System.out.println(-2 >> 3);
}
/**
* <h1>-2 >>> 3 过程分析</h1>
*
* <p> 10000000 .. 00000010:-2原码
* <p> 11111111 .. 11111101:取反得到-2反码
* <p> 11111111 .. 11111110:加1得到-2补码
* <p> 00011111 .. 11111111:-2 >>> 3结果,右移动3,溢出忽略,用0补位。
* <p> 00011111 .. 11111111:取反得到结果的反码,同原码
* <p> 10000000 .. 00000001:加1得到结果的补码,同原码
* <p> 536870911:真值
*/
@Test
public void noSignRightMoveOfBit() {
System.out.println(Integer.toBinaryString(-2 >>> 3));
System.out.println(-2 >>> 3);
}
6. 三元运算符
概念: 三目运算符,也叫三部运算符,也叫三元运算符。
- 公式:
X ? Y : Z,其中X为布尔类型表达式,当X的结果为true时返回Y,否则返回Z。 - Y和Z的返回值类型必须一致。
- 三目运算符一定要接它的返回值,它的返回值类型就是你Y和Z的返回值类型。
7. Math工具类
概念: java.lang.Math 工具类提供了大量用于数学运算的方法,Math类是final类,因此不能从Math类继承,Math类中的方法都是static方法,因此不必创建Math类的对象就可以直接使用类的方法。
Math.abs(-10):绝对值。Math.sqrt(16):平方根。Math.cbrt(8):立方根。Math.ceil(2.1):向上取整。Math.floor(2.9):向下取整。Math.max(1, 6):最大值。Math.min(1, 6):最小值。Math.pow(2, 3):a的b次幂。Math.round(2.4):四舍五入。Math.random():随机数:每次随机都生成一个[0-1)之间的数字。
随机数生成的代码,更建议使用
new Random().nextInt(5);,此时可以直接随机生成一个0到5范围内的int值。