title: 运算符
index_img: https://picss.sunbangyan.cn/2023/07/30/stdtw2.jpg
tags:
- Java SE
categories:
- Java SE
hide: false
excerpt: 运算符、类型转换、原码、反码、补码。
算数运算符
+、-、*
public class Main {
public static void main(String[] args) {
System.out.println(1 + 3); // 4
System.out.println(2 + 1.1); //3.1
System.out.println(1.1 + 1.3);//2.4000000000000004
System.out.println(2 * 3); //6
System.out.println(2 * 1.3); //2.6
System.out.println(3.1 * 2.2);//6.820000000000001
}
}
字符的+
- 字符会转为ASCII表中的对应数字
- 字符+数字
- 字符+字符
- 字符+字符串,这是字符串拼接
public class Main {
public static void main(String[] args) {
System.out.println(1 + 'a' + 1); //99
System.out.println('a' + 'b'); //195
System.out.println(1 + 'a' + 'b' + 1); //197
System.out.println('a' + "bc"); //abc
}
}
字符串的+
当
+
运算中出现字符串
,此时的两个数间+
不再是算数运算符了,而是字符串拼接操作连续
+
则从左到右执行
public class Main {
public static void main(String[] args) {
System.out.println(12 + 23); //25
System.out.println(12 + "23"); //1233
System.out.println(1 + 2 + 3 + "4" + "5"); //645
System.out.println("123" + true); // 123true
System.out.println(1 + 2 + "abc" + 2 + 1); //3abc21
}
}
/
public class Main {
public static void main(String[] args) {
System.out.println(10 / 2); // 5
System.out.println(10 / 3); //3
System.out.println(10.0 / 5); //2.0
System.out.println(10.0 / 3); //3.3333333333333335
}
}
- 类型不同,不能参与运算,需要类型转换,上方的例子发生了
隐式转换
- 小数参与运算得到的结果可能不正确。
%
用于执行取余操作。语法是a % b
%
运算符只可用于整型的操作数,包括int
、long
、byte
和short
。
public class Main {
public static void main(String[] args) {
System.out.println(10 % 2); //0
System.out.println(17 % 3); //2
System.out.println(-13 % 4);//-1
}
}
案例
获取各个数
提取一个整数 num 的倒数第 k 位数字:\(num/10^{k-1}\%10\)
public class Main {
public static void main(String[] args) {
int num = 3456;
byte k = 3;
int result = num / (int) Math.pow(10, k - 1) % 10;
System.out.println(result); // 4
}
}
类型转换
不同的数据类型不能直接计算。
隐式转换
类型小的会自动转为类型大的再参与运算。(联系下方原反补)
规则:自动补0,直到字节对齐。
byte
、short
、char
只要参与运算都会直接提升为int
,再计算。
public class Main {
public static void main(String[] args) {
byte a = 10;
short b = 11;
long k = 10;
long result = a + b + k;
//首先a和b都要转换为int运算,然后结果转换为long与k运算,结果是long类型
}
}
强制转换
规则:自动删除前面字节,直到字节对齐。(联系下方原反补)
格式:目标类型 变量名 = (目标类型) (被强转的数据)
强转可能结果会“错误”
public class Main {
public static void main(String[] args) {
byte a = 10;
short b = 11;
byte result = (byte) (a + b);
System.out.println(result); //21 且是byte类型,a+b的结果是int
}
}
public class Main {
public static void main(String[] args) {
int a = 200; // 补码(4字节):0000 0000 0000 0000 0000 0000 1100 1000
byte b = (byte) a; // 补码(1字节,去除前面3字节) 1100 1000
System.out.println(b); // 回推原码返回:0011 1000=-56
}
}
自增自减
不参与运算
单独占一行,都是原来的加或减1
public class Main {
public static void main(String[] args) {
byte a = 10;
System.out.println("a:" + a); //10
a++;
System.out.println("a:" + a); //11
a--;
System.out.println("a:" + a); //10
a++; //11
a--; //10
System.out.println("a:" + a); //10
}
}
参与运算
b=a++;先用(赋值)再++
b=++a;先++再用(赋值)
public class Main {
public static void main(String[] args) {
int a = 10;
int b = a++; //b=10,a=11
int c = ++a; //a=12,c=12
System.out.println("a:" + a); //12
System.out.println("b:" + b); //10
System.out.println("c:" + c); //12
int d = a++ + ++b - a--;
/*
相当于:d=x+y-z
x=a++,即x=12,a=13
y=++b,即y=b=11
z=a--,即z=13,a=12
d=12+11-13
*/
System.out.println("a:" + a);//12
System.out.println("b:" + b);//11
System.out.println("d:" + d);//10
}
}
赋值运算符
符号 | 说明 | 使用 |
---|---|---|
= | 左右相等 | \(a=b\) |
+= | 先+再赋值 | \(a+=b\) |
*= | 先*再赋值 | \(a*=b\) |
/= | 先/再赋值 | \(a/=b\) |
%= | 先%再赋值 | \(a\%=b\) |
+=,、*=,/=,%=
a+=b
与a=a+b
不相等,此类运算都发生了自动强制转换- 强转的类型取决于左边
public class Main {
public static void main(String[] args) {
int a = 10;
long b = 11;
a += b;
System.out.println(a); //21
}
}
反编译如下,可以看到强转
public class Main {
public Main() {
}
public static void main(String[] var0) {
int var1 = 10;
long var2 = 11L;
var1 = (int)((long)var1 + var2);
System.out.println(var1);
}
}
关系运算符
符号 | 说明 |
---|---|
== | 判断是否相等,成立则true ,否则false |
!= | \(\dots\) |
> | \(\dots\) |
< | \(\dots\) |
\(\ge\) | \(\dots\) |
\(\le\) | \(\dots\) |
关系运算符的结果都是
boolean
类型
public class Main {
public static void main(String[] args) {
System.out.println(1 == 2); //false
System.out.println('a' != 7); //true
System.out.println('a' != 97); //false
}
}
逻辑运算符
可联系下方原反补深入了解。
符号 | 说明 |
---|---|
& | 两边都true则true |
| | 一边true则true |
! | 取反 |
^ | 相同为false,否则true |
public class Main {
public static void main(String[] args) {
System.out.println(true & false); //false
System.out.println(true & true); //true
System.out.println(!true); //false
System.out.println(true ^ true); //false
System.out.println(true ^ false); //true
}
}
符号 | 说明 |
---|---|
&& | 与&功能相同,但左边为false则不再判断右边 |
|| | 与|功能相同,但左边为true则不再判断右边 |
public class Main {
public static void main(String[] args) {
int a = 1;
int b = 1;
System.out.println(a == 2 && (b++) == 2); //false
System.out.println(b); // 1
}
}
三元运算符
格式:关系表达式?表达式1:表达式2;
结果必须被使用,如果true,则结果是表达式1,否则是表达式2
public class Main {
public static void main(String[] args) {
String result = 3 > 5 ? "结果是true" : "结果是false";
System.out.println(result); //结果是false
}
}
原码、反码、补码
原码
符号位(2)+数值二进制(7)
-
0为+,1为-
-
最大值:
0 1111111
即+127 -
最小值:
1 1111111
即-127
直接用原码做正数运算不会出错。
如1+2
0000 0001 +0000 0010=0000 0011=3
做负数运算会出错
如-1+2
1000 0001+0000 0010 =1000 0011 =-3
反码
解决原码不能计算负数的问题
规则
- 正数的反码与原码相同
- 负数的反码在原码的基础上,符号位不变,数值取反
正常情况
- 如-4-1
- 反码-1:1111 1011 - 0000 0001=
1
111 1010- 反码回推原码:1000 0101=-5
异常情况(跨0会产生“1”误差)
- 如-0+1
- 反码+1: 1111 1111 + 0000 0001=0000 00000=+0
- 误差来源:0有+0和-0两种形式
补码(计算和存储采用的形式)
解决反码的误差问题
规则
- 正数的补码与原码相同。
- 负数的补码是其反码加1
标签:10,System,运算符,println,true,public,out From: https://www.cnblogs.com/SimpleWord/p/17689197.html按照规则,0只有一种形式
- +0:0000 0000
- -0: 0000 0000
跨0计算
- 如-4+2
- 补码+2:1111 1100 + 0000 0010=
1
111 1110- 补码回推(符号位)原码:1000 0010 = -2
-128补码
- 10000 0000=-128
计算机计算和存储采用补码,一个字节的范围是-128~127,打印时通常以十进制还原给我们。