此资料是根据黑马程序员Java零基础视频教程提供的笔记进行修改而成,仅用于个人学习。
学习视频:https://www.bilibili.com/video/BV17F411T7Ao/?p=30&vd_source=a0fb36c5a191d7be68335738a8b342a2
1. 运算符和表达式
1.1 运算符
就是对常量或者变量进行操作的符号。
比如: + - * / %
1.2 表达式
用运算符把常量或者变量连接起来的,符合Java语的式子就是表达式。
比如:a + b 这个整体就是表达式。
而其中+是算术运算符的一种,所以这个表达式也称之为算术表达式。
2. 算术运算符
2.1 分类
+ - * / %
2.2 实例
public static void main(String[] args) {
//+
System.out.println(3 + 2);//5
//-
System.out.println(5 - 1);//4
//* (shift + 数字8或者 数字键盘区的*)
System.out.println(7 * 9);//63
//如果在计算的时候有小数参与
//结论:
//在代码中,如果有小数参与计算,结果有可能不精确的。
//为什么呢?
//暂时只要知道这个结论就可以了。
//具体的原因,我们到了JavaSE的时候,会再详细的讲解。
System.out.println(1.1 + 1.1); //2.2
System.out.println(1.1 + 1.01); //2.1100000000000003,出现了误差
System.out.println(1.1 - 1.01); //0.09000000000000008,出现了误差
System.out.println(1.1 * 1.01); //1.1110000000000002,出现了误差
// /
System.out.println( 10 / 3); //3 整数相除结果只能得到整除
System.out.println(10.0 / 3); //3.3333333333333335 结果想要是小数,必须要有小数参数,强制转换
// %:取模、取余。
//他做的也是除法运算,只不过获取的是余数而已。
System.out.println(10 % 2); //0
System.out.println(10 % 3); //1
//应用场景:
//可以利用取模来判断一个数是奇数还是偶数
System.out.println(15 % 2); //1 除2有余数,所以是奇数
}
2.3 注意点
- 在代码中,如果有小数参与计算,结果有可能不精确。
- 整数相除结果只能得到整除,如果结果想要是小数,必须要有小数参数。
2.4 运算特点
+ - * :跟小学数学中一模一样没有任何区别。
%:取模、取余。
应用场景:
1.可以用取模来判断,A是否可以被B整除
A % B 10 % 3
2.可以判断A是否为偶数
A % 2 如果结果为0.那么证明A是一个偶数。如果结果为1,那么证明A是一个奇数
3.在以后,斗地主发牌
三个玩家
把每一张牌都定义一个序号
拿着序号 % 3 如果结果为1,就发给第一个玩家。
如果结果为2,那么就发给第二个玩家
如果结果为0,那么就发给第三个玩家
2.5 练习:数值拆分
需求:键盘录入一个三位数,将其拆分为个位、十位、百位后,打印在控制台
2.5.1 代码示例
//1.键盘录入一个三位数
//导包 --- 创建对象 --- 接收数据
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个三位数");
int number = sc.nextInt();//123
//2.获取这个三位数的个位、十位、百位并打印出来
//公式:
//针对于任意的一个数而言
//个位: 数字 % 10
int ones = number % 10;
//十位: 数字 / 10 % 10
int tens = number / 10 % 10;
//百位: 数字 / 100 % 10
int hundreds = number / 100 % 10;
//输出结果
System.out.println(ones);
System.out.println(tens);
System.out.println(hundreds);
2.5.2 拆分公式
获取任意一个数上每一位数。
个位:数字 % 10
十位:数字 / 10 % 10
百位:数字 / 100 % 10
千位:数字 / 1000 % 10
。。。以此类推。。。
后期可以用循环进行处理
3. 隐式转换
3.1 概念
也叫自动类型提升,就是把一个取值范围小的数据或者变量,赋值给另一个取值范围大的变量。此时不需要我们额外写代码单独实现,是程序自动帮我们完成的。
简单记忆:
就是小的给大的,可以直接给。
3.2 两种提升规则
-
取值范围小的,和取值范围大的进行运算,小的会先提升为大的,再进行运算。
-
byte、short、char三种类型的数据在运算的时候,都会直接先提升为int,然后再进行运算。
3.3 取值范围从小到大的关系
byte < short < int < long < float < double
4. 隐式转换的练习
请看下面案例是否有误,如果有问题,请说出原因,如果没有问题,请说出运算过程和运算结果
4.1 案例一
double d = 10;
System.out.println(d);//10.0
解释:
10是整数,整数默认是int类型的。
而在取值范围的顺序中: byte < short < int < long < float < double
在赋值的时候把一个int类型的赋值给了一个double类型的,把一个小的赋值给一个大的是可以直接给的。
4.2 案例二
byte b = 100;
int i = b; //在-128-127范围中,可以成功赋值
System.out.println(i); //100
解释:
因为byte的取值范围是小的,int的取值范围是大的,在底层进行了隐式转换,不需要我们额外写代码单独实现,是可以直接赋值。
4.3 案例三
int i = 10;
long n = 20L;
??? result = i + n;
问变量result是什么类型的? long类型
解释:
变量i是int类型的,变量n是long类型的。
而在取值范围的顺序中:byte < short < int < long < float < double
变量i里面的值会自动提升为long类型的,最终的结果其实就是两个long相加,那么最终的result是long类型的。
4.4 案例四
int i = 10;
long n = 100L;
double d = 20.0;
??? result = i + n + d;
问变量result是什么类型的? double类型
解释:
变量i是int类型,变量n是long类型,变量d是double类型。
而在取值范围的顺序中:byte < short < int < long < float < double
所以变量i和变量n里面的值在参与运算的时候,都会进行类型提升,变成double。
最终其实就是三个double进行相加,那么最终的结果就是double类型的。
4.5 案例五
byte b1 = 10;
byte b2 = 20;
??? result = b1 + b2;//int
问变量result是什么类型的? int类型
解释:
因为b1和b2都是byte类型的。所以在参与计算的时候,变量b1和变量b2里面的值都会自动提升为int类型的。最终其实就是两个int类型的相加,最终结果也是int类型的。
4.6 案例六
byte b = 10;
short s = 20;
long n = 100L;
??? result = b + s + n;
问变量result是什么类型的? long类型
解释:
变量b是byte类型的,变量s是short类型的,变量n是long类型的。
byte,short,char类型的变量在参与运算的时候,变量里面的值会直接先提升为int。
第一步:变量b和变量s里面的值会先提升为int参与运算。
int + int + long
第二步:而long类型的取值范围是大于int的取值范围的。
所以变量b和变量s里面的值会再次提升为long。
long + long + long。
所以最终结果是long类型的。
5. 强制转换
5.1 概念
如果要把一个取值范围大的数据或者变量赋值给另一个取值范围小的变量。是不允许直接操作。
如果一定要这么干,就需要加入强制转换。
5.2 书写格式
目标数据类型 变量名 = (目标数据类型)被强转的数据;
简单理解:
要转成什么类型的,那么就在小括号中写什么类型就可以了。
5.3 案例
5.3.1 案例一
注意转换后的取值范围
public class OperatorDemo2 {
public static void main(String[] args) {
double a = 12.3;
int b = (int) a;
System.out.println(b);//12
// int c = 300;
// byte d = (byte)c; 超过范围-128~127,报错
}
}
5.3.2 案例二
注意整体打括号
public static void main(String[] args) {
byte b1 = 10;
byte b2 = 20;
//现在我们要强转的是谁?
//b1 + b2计算之后的结果是int类型的,需要将最后的结果作为一个整体进行强转
// (byte)b1 + b2 强转的是b1,并不是最终的结果
byte result = (byte)(b1 + b2); //整体打括号
System.out.println(result);//30
}
注意点:
强制转换有可能会导致数据发生错误。(数据的精度丢失)
6. 字符串的+操作
6.1 核心技巧
- 当+操作中出现字符串时,此时就是字符串的连接符,会将前后的数据进行拼接,并产生一个新的字符串。
- 当连续进行+操作时,从左到右逐个执行的。
7. 字符串相加的练习
7.1 案例一
1 + "abc" + 1
结果:1abc1
解释:
第一步: 1 + “abc”。在这个过程中,有字符串参与的,所以做的是拼接操作,产生一个新的字符串"1abc"
第二步: “1abc” + 1。这个过程中,有字符串参与的,所以做的也是拼接操作,产生一个新的字符串"1abc1"
7.2 案例二
1 + 2 + "abc" + 2 + 1
结果:3abc21
解释:
第一步:1 + 2 。在这个过程中,没有字符串参与的,所以做的是加法运算,结果为3。
第二步:3 + “abc”。在这个过程中,有字符串参与的,所以做的是拼接操作,产生一个新的字符串"3abc"。
第三步:“3abc” + 2。在这个过程中,有字符串参与的,所以做的是拼接操作,产生一个新的字符串"3abc2"。
第四步:“3abc2” + 1。在这个过程中,有字符串参与的,所以做的是拼接操作,产生一个新的字符串“3abc21”
7.3 案例三
String name = "黑默丁格";
System.out.println("我的名字是" + name);
结果: 我的名字是黑默丁格
解释:当字符串跟变量相加的时候,实际上是跟变量里面的值进行拼接。
7.4 案例四
7.5 案例五–数值拆分添加提示语句
//1.键盘录入一个三位数
//导包 --- 创建对象 --- 接收数据
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个三位数");
int number = sc.nextInt();//123
//2.获取这个三位数的个位、十位、百位并打印出来
//公式:
//针对于任意的一个数而言
//个位: 数字 % 10
int ones = number % 10;
//十位: 数字 / 10 % 10
int tens = number / 10 % 10;
//百位: 数字 / 100 % 10
int hundreds = number / 100 % 10;
//输出结果,使用+进行字符串的拼接
System.out.println(“个位数是:”+ones);
System.out.println(“十位数是:”+tens);
System.out.println(“百位数是:”+hundreds);
8. 字符的+操作
8.1 规则
当+操作中出现了字符,会拿着字符到计算机内置的ASCII码表中去查对应的数字,然后再进行计算。
8.2 案例一
char c = 'a';
int result = c + 2;
System.out.println(result);//99
char c1 = (char)result;
System.out.println(c1);//c
/*
ASCII码表中:
'a' ----- 97
'A' ----- 65
*/
8.3 案例二
public static void main(String[] args) {
System.out.println((1+'a')); //98
System.out.println(('a'+"abc")); //aabc,有字符串的参与,会转换成字符串
}
9. 算术运算符的总结
9.1 分类
+ - * / % 这些操作跟小学数学几乎是一模一样的。
9.2 注意点
- / 和 % 的区别:他们两个都是做除法运算,/取结果的商。% 取结果的余数。
- 整数操作只能得到整数,如果想要得到小数,必须有浮点数参与运算。
- 字符串只有+操作即拼接操作,没有其他操作。
10. 自增自减运算符
10.1 分类
++ 自增运算符
-- 自减运算符
++:就是把变量里面的值+1
–:就是把变量里面的值-1
10.2 两种用法
- 先用后加:放在变量的前面,我们叫做先++。 比如:++a
- 先加后用:放在变量的后面,我们叫做后++。 比如:a++
10.3 注意点
不管是先++,还是后++。单独写在一行的时候,运算结果是一模一样的。
10.4 案例一
public static void main(String[] args) {
//++ 和 --
int a = 10;
//表示把变量a里面的值+1
a++;
System.out.println(a);//11
//表示把变量a里面的值+1
++a;
System.out.println(a);//12
//表示把变量a里面的值-1
a--;
System.out.println(a);//11
//表示把变量a里面的值-1
--a;
System.out.println(a);//10
}
10.5 案例二
public static void main(String[] args) {
int x = 10;
//后++:先用后加
//先把x变量中的值拿出来用,赋值给y,然后再进行自增。
//赋值给y的值是自增前的。
int y = x++;// x = 11 y = 10
//先++:先加后用
//先把x进行自增,然后把自增后的结果赋值给左边的变量
//先把x自增,变成12,然后再把自增之后的12赋值给z
int z = ++x;//x = 12 z = 12
System.out.println("x:" + x);//12
System.out.println("y:" + y);//10
System.out.println("z:" + z);//12
}
10.6 自增自减运算符的应用场景
某些情况下,变量需要进行加1或者减1的时候使用。
比如:过生日多一岁,就用到了自增运算符。
比如:购物商场中,选择商品数量,也用到了自增或者自减运算符。
比如:统计很多数据中,有多少个数据满足要求,也用到了自增运算符。
后续使用循环的时候,经常用到自增自减。
11. 赋值运算符
11.1 常见赋值运算符
11.2 细节
- = 的运算过程:就是把等号右边的结果赋值给左边的变量
- +=、-=、*=、/=、%= 就是把左边跟右边进行运算,把最终的结果赋值给左边,对右边没有任何影响。
- +=、=、*=、/=、%= 底层都隐藏了一个强制类型转换
11.3 案例一
public class OperatorDemo6 {
public static void main(String[] args) {
//1.最为简单的赋值运算符用法
int a = 10; //就是把10赋值给变量a
System.out.println(a); //10
//2.如果等号右边需要进行计算。
int b = 20;
int c = a + b;//先计算等号右边的,把计算的结果赋值给左边的变量
System.out.println(c); //30
//3.特殊的用法
a = a + 10;//先计算等号右边的,把计算的结果赋值给左边的变量 或a += 10;
System.out.println(a);//20
}
}
11.4 案例二
public static void main(String[] args) {
//+=
//规则:将左边和右边进行相加,然后再把结果赋值给左边
int a = 10;
int b = 20;
//把a+b,再把结果赋值给左边的变量a
a += b;
//等同于 a = (int)(a + b);
System.out.println(a);//30
System.out.println(b);//20
//细节:
//+=,-=,*=,/=,%= 底层都隐藏了一个强制类型转换
short s = 1;
//把左边和右边进行相加,得到结果2,再赋值给左边的变量
s += 1;
//等同于:s = (short)(s + 1);
System.out.println(s);//2
}
11.5 案例三
public class OperatorDemo7 {
public static void main(String[] args) {
//扩展赋值运算符
int a = 10;
int b = 20;
a += b;//把左边和右边相加,再把最终的结果赋值给左边,对右边没有任何影响
// 相当于 a = a + b;
System.out.println(a);//30
System.out.println(b);//20
}
}
12. 关系运算符
又叫比较运算符,其实就是拿着左边跟右边进行了判断而已。
12.1 分类
符号 | 解释 |
---|---|
== | 就是判断左边跟右边是否相等,如果成立就是true,如果不成立就是false |
!= | 就是判断左边跟右边是否不相等,如果成立就是true,如果不成立就是false |
> | 就是判断左边是否大于右边,如果成立就是true,如果不成立就是false |
>= | 就是判断左边是否大于等于右边,如果成立就是true,如果不成立就是false |
< | 就是判断左边是否小于右边,如果成立就是true,如果不成立就是false |
<= | 就是判断左边是否小于等于右边,如果成立就是true,如果不成立就是false |
12.2 注意点:
- 关系运算符最终的结果一定是布尔类型的。要么是true,要么是false
- 在写==的时候,千万不要写成=
- 组合符号中间没有空格,要写在一起
12.3 案例
public static void main(String[] args) {
public static void main(String[] args) {
/* 需求:
您和您的约会对象正试图在餐厅获得一张桌子。
键盘录入两个整数,表示你和你约会对象衣服的时髦度。(手动录入0~10之间的整数,不能录其他)
如果你的时髦程度大于你对象的时髦程度,相亲就成功,输出true。
否则输出false。*/
//1.键盘录入两个整数表示衣服的时髦度
Scanner sc = new Scanner(System.in);
System.out.println("请输入我们自己的衣服时髦度");
int myFashion = sc.nextInt();
System.out.println("请输入相亲对象衣服的时髦度");
int girlFashion = sc.nextInt();
//2.把我衣服的时髦度跟女孩的时髦度进行对比就可以了
boolean result = myFashion > girlFashion;
//3.打印结果
System.out.println(result);
}
}
13. 逻辑运算符
13.1 & 和 | 的使用
&:逻辑与(而且)
两边都为真,结果才是真,只要有一个为假,那么结果就是假。
|:逻辑或(或者)
两边都为假,结果才是假,只要有一个为真,那么结果就是真。
代码示例:
// & //两边都是真,结果才是真。
System.out.println(true & true);//true
System.out.println(false & false);//false
System.out.println(true & false);//false
System.out.println(false & true);//false
System.out.println("===================================");
// | 或 //两边都是假,结果才是假,如果有一个为真,那么结果就是真。
System.out.println(true | true);//true
System.out.println(false | false);//false
System.out.println(true | false);//true
System.out.println(false | true);//true
13.1.1 使用场景
根据固定的场景,来选择使用&还是使用|。
-
用户登录。
用户名输入正确 & 密码输入正确。
因为只有用户名和密码同时都正确了,那么才能成功登录,只要有一个失败了都不行。
使用技巧:
当我们需要同时满足左边和右边两种情况时,可以使用且。
-
丈母娘选女婿
丈母娘:女婿啊,你要么买个房子,要么买辆车。就可以把我的小棉袄穿走了。
买个房子 | 买辆车
两个条件中,只要满足其中一个,就可以穿走小棉袄了。
使用技巧:
当两种条件只要满足其中一个的时候,可以使用或。
13.2 ^(异或)的使用
在以后用的不多,了解一下即可。
计算规则:如果两边相同,结果为false,如果两边不同,结果为true。 异(不同)就对
巧记:
代码示例:
//^ //左右不相同,结果才是true,左右相同结果就是false
System.out.println(true ^ true);//false
System.out.println(false ^ false);//false
System.out.println(true ^ false);//true
System.out.println(false ^ true);//true
13.3 !(取反)的使用
是取反,也叫做非。
计算规则:false取反就是true,true取反就是false
温馨提示:取反最多只用一个。两次就不变,三次等同一次。
代码示例:
System.out.println(!false);//true
System.out.println(!true);//false
System.out.println(!!false);//注意点:取反最多只用一个。
14. 短路逻辑运算符
14.1 &&
运算结果跟&是一模一样的,只不过具有短路效果。
14.2 ||
运算结果跟|是一模一样的。只不过具有短路效果。
14.3 逻辑核心
当左边不能确定整个表达式的结果,右边才会执行。
当左边能确定整个表达式的结果,那么右边就不会执行了。从而提高了代码的运行效率。
14.3.1 举例
-
用户登录案例
用户名正确 & 密码正确
如果使用一个&,不管用户名是否正确都会去验证密码。
思考:
如果用户名输入正确了,那么我们再判断密码是否正确,是符合业务逻辑的。
但是如果用户名输入错误了,那么现在还有必要去比较密码吗?没有不要了。
如果使用一个&,那么左边和右边不管什么情况下,都会执行。
用户名正确 && 密码正确
如果用户名输入正确了,那么才会验证密码是否输入正确。
如果用户名输入错误了,那么就不会再去验证密码是否正确,最终的结果直接为false。从而提高了程序运行的效率。
-
丈母娘选女婿
有房 | 有车
首先先看看有没有房,发现有,然后再去看看有没有车。
思考:
既然都有房子,干嘛还要去看车呢?多此一举。
有房 || 有车
首先先看看有没有房,如果有,那么右边就不执行了。最终的结果直接为true。
如果没有房子,才会去看右边有没有车。
14.3.2 案例
public static void main(String[] args) {
//1.&&
//运行结果跟单个&是一样的
//表示两边都为真,结果才是真
System.out.println(true && true);//true
System.out.println(false && false);//false
System.out.println(false && true);//false
System.out.println(true && false);//false
//2.||
//运行结果跟单个|是一样的
//表示两边都为假,结果才是假
System.out.println(true || true);//true
System.out.println(false || false);//false
System.out.println(false || true);//true
System.out.println(true || false);//true
//3.短路逻辑运算符具有短路效果
//简单理解:当左边的表达式能确定最终的结果,那么右边就不会参与运行了
int a = 10;
int b = 10;
boolean result = ++a < 5 & ++b < 5;
System.out.println(result);//false
System.out.println(a);//11
System.out.println(b);//11 会去执行 ++b < 5
//3.对比
int c = 10;
int d = 10;
boolean result = ++c < 5 && ++d < 5;
System.out.println(result);//false
System.out.println(c);//11
System.out.println(d);//10 不会去执行 ++b < 5,具有短路效果
}
14.3.3 总结
&& 和 & 、||和|的运行结果都是一模一样的。
但是短路逻辑运算符可以提高程序的运行效率。
14.3.4 建议
最为常用: && || !
14.4 练习
package com.itheima.test;
import java.util.Scanner;
public class Test3 {
public static void main(String[] args) {
/*数字6是一个真正伟大的数字,键盘录入两个整数。
如果其中一个为 6,最终结果输出true。
如果它们的和为 6的倍数。最终结果输出true。
其他情况都是false。*/
//分析:
//1.键盘录入两个整数
// 变量a 变量b
//2.a == 6 || b == 6 || (a + b) % 6 == 0
//如果满足其中一个,那么就可以输出true
//键盘录入两个整数
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数");
int number1 = sc.nextInt();
System.out.println("请输入第二个整数");
int number2 = sc.nextInt();
//可以短路逻辑运算符去连接三个判断
boolean result = number1 == 6 || number2 == 6 || (number1 + number2) % 6 == 0;
System.out.println(result);
}
}
15. 三元运算符
又叫做:三元表达式或者问号冒号表达式。
15.1 格式
关系表达式 ? 表达式1 :表达式2 ;
15.2计算规则
- 计算关系表达式的值。
- 如果关系表达式的值为真,那么执行表达式1。
- 如果关系表达式的值为假,那么执行表达式2。
15.3 注意点
三元运算符的最终结果一定要被使用,要么赋值给一个变量,要么直接打印出来。
15.4 案例
public class OperatorDemo12 {
public static void main(String[] args) {
//需求:求两个数的较大值
int a = 10;
int b = 20;
//格式:关系表达式 ? 表达式1 : 表达式2 ;
//注意点:
//三元运算符的最终结果一定要被使用。
//要么赋值给一个变量,要么直接输出。
int max = a > b ? a : b ;
System.out.println(max); //20
System.out.println(a > b ? a : b); //20
}
}
16. 练习1-两只老虎
需求:
动物园里有两只老虎,两只老虎的体重分别为通过键盘录入获得,
请用程序实现判断两只老虎的体重是否相同。
代码示例:
//1.获取两只老虎的体重
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一只老虎的体重");
int weight1 = sc.nextInt();
System.out.println("请输入第二只老虎的体重");
int weight2 = sc.nextInt();
//2.利用三元运算符求出最终结果
String result = weight1 == weight2 ? "相同" : "不相同";
System.out.println(result);
17. 练习2-求三个数的最大值
需求:
一座寺庙里住着三个和尚,已知他们的身高分别为150cm、210cm、165cm。
请用程序实现获取这三个和尚的最高身高。
代码示例:
//1.定义三个变量记录和尚的身高
int height1 = 150;
int height2 = 210;
int height3 = 165;
//2.利用三元运算符求出两个数中的较大值。
int temp = height1 > height2 ? height1 : height2;
//3.求出最终的结果
int max = temp > height3 ? temp : height3;
System.out.println(max);
18. 运算符的优先级
在Java中涉及了很多的运算符,每一种运算符都有各自的优先级。但是这些优先级不需要记忆。
咱们只要知道其中一点:
小括号优先于所有。
19. 原码、反码、补码
19.1 原码
19.1.1 原码的介绍
十进制数据的二进制表现形式,最左边是符号位,0为正,1为负
19.1.2 原码的计算
- 正数的原码反码补码是其本身。 如 7的原码:0000 0111
- 负数的原码符号位为1,数值位为其绝对值。 如 -7的原码:1000 0111
若 X = +1110, 则[X]原 = 0,1110 用逗号隔开 符号位和数值位
若 X = -1110, 则[X]原 = 1,1110 用逗号隔开 符号位和数值位
19.1.3 原码的范围
注:1Byte (字节) = 8 bit (位)
所以使用原码表示一个字节的范围是(0111 1111 ~ 1111 1111),即(-127~127)
19.1.4 原码计算的弊端
利用原码进行计算的时候,如果是正数完全没有问题;但是如果是负数计算,结果就出错,实际运算的方向跟正确的运算方向是相反的。
19.2 反码
19.2.1 反码出现的目的
为了解决原码不能计算负数的问题而出现的。
19.2.2 反码的计算规则
正数的原码反码补码是其本身,负数的反码是在原码的基础上,符号位不变。数值位取反,0变1,1变0。有 +0 -0 之分
19.2.3 常见负数的反码
19.2.4 反码的弊端
负数运算的时候,如果结果不跨O,是没有任何问题的,但是如果结果跨O,跟实际结果会有1的偏差。
19.3 补码
计算机中的存储和计算都是以补码的形式进行的。
19.3.1 补码出现的目的
为了解决负数计算时跨0的问题而出现的。
19.3.2 补码的计算规则
正数的原码反码补码是其本身,负数的补码在反码的基础上+1。
另外补码还能多记录一个特殊的值-128,该数据在1个字节下,没有原码和反码。
19.3.3 常见负数的补码
19.4 综合计算
20. 隐式转换与强制转换的底层原理
如下方:将byte类型转换成int类型,直接高位补0
如下方:int类型强制转换为byte类型,直接去掉高位
巧用电脑计算器
打开程序员模式,设置成BYTE模式,鼠标点击对应的0、1会发生变换,即可看到对应的其他进制数值。
计算机是用的补码进行存储和计算的。
21. 逻辑与&的计算
22. 逻辑或|的计算
23. 左移<<、右移>>运算符的计算
左移一次,数值大小乘2,左移2次,数值大小乘4……
左移n次,数值大小乘2n
右边移空的 低位补0
右移一次,数值大小除2,右移2次,数值大小除4……
右移n次,数值大小除2n
左边移空的 高位补上原来的符号位数值。
24. 无符号右移运算符>>>的计算
不管符号位,高位直接补0。