整数运算
1015字约3分钟
2024-08-09
四则运算
Java
的整数运算遵循四则运算规则,可以使用任意嵌套的小括号。四则运算规则和初等数学一致
int i = 10 * (20 -10);
整数的数值表示不但是精确的,而且整数运算永远是精确的,即使是除法也是精确的,因为两个整数相除只能得到结果的整数部分
int i = 10 / 7; // 1
求余运算使用 %
int i = 10 % 7; // 3
溢出
整数由于存在范围限制,如果计算结果超出了范围,就会产生溢出,而溢出不会出错,却会得到一个奇怪的结果
public class Pratice {
public static void main(String[] args) {
int i = 2147483640;
int j = 8;
System.out.println(i + j); // -2147483648
}
}
2147483640
和 8
换成二进制做加法
0111 1111 1111 1111 1111 1111 1111 1000
+ 0000 0000 0000 0000 0000 0000 0000 1000
-----------------------------------------
1000 0000 0000 0000 0000 0000 0000 0000
最高位计算结果为 1
,因此,加法结果变成了一个负数
自增自减
public static void main(String[] args) {
int i = 7;
i++; // 8
i--; // 7
++i; // 8
--i; // 7
}
注意:i++
是加 1
返回原来的i值,++i
是返回加 1
后的值
移位运算
int i = 7; // 00000000 00000000 00000000 00000111 = 7
int a = i << 1; // 00000000 00000000 00000000 00001110 = 14
int b = i << 2; // 00000000 00000000 00000000 00011100 = 28
int c = i << 28; // 01110000 00000000 00000000 00000000 = 1879048192
int c = i << 29; // 11100000 00000000 00000000 00000000 = -536870912
向左移 n
,就是乘以 2^n
,左移最高位变为 1
结果会变为负数
int i = -536870912;
int a = i >> 1; // 11110000 00000000 00000000 00000000 = -268435456
int b = i >> 2; // 11111000 00000000 00000000 00000000 = -134217728
int c = i >> 28; // 11111111 11111111 11111111 11111110 = -2
int d = i >> 29; // 11111111 11111111 11111111 11111111 = -1
// 注意:在计算机中运算的话,都是以补码的形式,而中间的转化过程计算机可以十分迅速的转化,这个就不用我们操心;
// 这里以 -2 右移为例
10000000 00000000 00000000 00000010 // 原码,原码->反码:符号位不变,其他位取反
11111111 11111111 11111111 11111101 // 反码,反码->补码:+1
11111111 11111111 11111111 11111110 // 补码
11111111 11111111 11111111 11111111 // 补码,补码->原码:符号位不变,其他位取反 +1
11111111 11111111 11111111 11111110 // 反码
10000000 00000000 00000000 00000001 // 原码
向右移 n
,就是除以 2^n
,不过负数右移,最高位 1
不动,始终是一个负数
int n = -536870912;
int a = n >>> 1; // 01110000 00000000 00000000 00000000 = 1879048192
int b = n >>> 2; // 00111000 00000000 00000000 00000000 = 939524096
int c = n >>> 29; // 00000000 00000000 00000000 00000111 = 7
int d = n >>> 31; // 00000000 00000000 00000000 00000001 = 1
无符号的右移运算,使用 >>>
,它的特点是不管符号位,右移后高位总是补 0
,因此,对一个负数进行 >>>
右移,它会变成正数,原因是最高位的1变成了 0
对 byte
和 short
类型进行移位时,会首先转换为 int
再进行位移
位运算
位运算是按位进行与、或、非和异或的运算
与运算的规则是,必须两个数同时为 1
,结果才为 1
n = 0 & 0; // 0
n = 0 & 1; // 0
n = 1 & 0; // 0
n = 1 & 1; // 1
或运算的规则是,只要任意一个为 1
,结果就为 1
n = 0 | 0; // 0
n = 0 | 1; // 1
n = 1 | 0; // 1
n = 1 | 1; // 1
非运算的规则是,0
和 1
互换
~5; // -6
PS
:有兴趣自己去了解,百度 Java
位非 ~
运算符详解
异或运算的规则是,如果两个数不同,结果为 1
,否则为 0
n = 0 ^ 0; // 0
n = 0 ^ 1; // 1
n = 1 ^ 0; // 1
n = 1 ^ 1; // 0
运算优先级
()
!
~
++
--
*
/
%
+
-
<<
>>
>>>
&
|
+=
-=
*=
/=
类型自动提升与强制转型
在运算过程中,如果参与运算的两个数类型不一致,那么计算结果为较大类型的整型。例如,short
和 int
计算,结果总是 int
,原因是 short
首先自动被转型为 int
public class Main {
public static void main(String[] args) {
short s = 1234;
int i = 123456;
int x = s + i; // s自动转型为int
short y = s + i; // 编译错误!
}
}