目录
数字在计算机中是以补码的形式存在
0000 0000 0000 0010 2 的原码
1000 0000 0000 0010 -2 的原码
1111 1111 1111 1101 -2 的反码
1111 1111 1111 1110 -2 的补码
不信的话可以打印System.out.println(Integer.toBinaryString(-2));
java运算符和它的优先级
优先级 | 运算符 |
---|---|
1级 | 分割符([]、()、; . ,) |
2级 | 对象归类运算符(instanceof)、逻辑非(!)、自增运算符(++)、自减运算符(–)、按位非运算符(~) |
3级 | 算术乘除运算符(*、/、%) |
4级 | 算术加减运算符(+、-) |
5级 | 移位运算符(>>、 >>>、 <<) |
6级 | 大小关系运算符(> 、>=、<、<=) |
7级 | 相等关系运算符(==、!=) |
8级 | 按位与运算符(&) |
9级 | 按位异或运算符(^) |
10级 | 按位或运算符 |
11级 | 逻辑与运算符(&&) |
12级 | 逻辑或运算符 |
13级 | 三目运算符(? : ) |
14级 | 赋值运算符(!=、=、+=、-=等) |
不常见运算符的使用
instanceof是对象归类运算符,左边是对象名,右边是类名
例如:a是一个对象名, A是一个类的名字
if(a instanceof A) {
System.out.println("t是instanceOfDemo的实例");
}
~按位非运算符
对二进制进行运算(正数符号位位0,负数符号位为1)
原码:
- 正数的原码是自己的二进制
- 负数的原码就是正数的二进制,然后最高为变为1
反码:
- 正数的反码就是自己的原码
- 负数的反码,就是除了最高位的符号位之外,全部取反
补码:
- 正数的补码就是自己的原码
- 负数的补码就是反码 + 1
结论:
- 正数的原码、反码、补码相同
/*
* 按位取反运算符是将内存中的补码按位取反(包括符号位)
* ~5的值-6
* 正数的原码、反码、补码都一样
* 5的二进制为(即源码、反码、补码): 0000 0000 0000 0000 0000 0000 0000 0101
* ~5运算:
* 取反: 1111 1111 1111 1111 1111 1111 1111 1010 (这是负数的补码) 就是 -6 的二进制码
* 使用-6的二进制验证与上述补码结果一样
* Integer z = -6;
* System.out.println(z.toBinaryString(z));
* 11111111111111111111111111111010
* 结论: 负数的二进制就是补码
*/
/* 负数与正数不一样
* -11的原码为: 1000 0000 0000 0000 0000 0000 0000 1011
* ~-11运算:
* 取反(: 最高位为符号位不变 0为正数 1为负数)
* 取反结果为: 1111 1111 1111 1111 1111 1111 0000 0100
* 负数的反码+1是补码
* 补码: 1111 1111 1111 1111 1111 1111 1111 0101
* Integer t = -11;
* System.out.println(t.toBinaryString(t));
* -11的二进制为: 1111 1111 1111 1111 1111 1111 1111 0101
* 结论: 负数的二进制就是补码
*/
Integer a =5;
System.out.println(a.toBinaryString(a));
System.out.println(~5);
Integer z = -6;
System.out.println(z.toBinaryString(z));
Integer t = -11;
System.out.println(t.toBinaryString(t));
>>、>>>、<<移位运算符
对二进制进行运算(正数符号位位0,负数符号位为1)
- 左移((<<) 带符号左移,正数左移最高位(符号位)补0,负数左移最高位(符号位)补1,符号位是左边第一位 ,(高位)左边舍弃,(低位)左边补0,符号位除外,结果相当于乘2
- 右移(>>) 带符号右移。正数右移高位(符号位)补0,负数右移高位(符号位)补1,符号位是左边第一位, (高位)左边补0,(低位)右边舍弃,符号位除外,结果相当于乘2
- 右移(>>>)无符号右移, (高位)左边补0,(低位)右边舍弃
/*
* 移位运算符
* >>:按二进制形式把所有的数字向右移动对应位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1。符号位不变。
* >>>:二进制右移补零操作符,左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充
* -8 >> 2
* 1111 1111 1111 1000
* 1000 0000 0000 0010
* 0000 0000 0000 1000
* 0000 0000 0000 0100
* 2 转换为二进制数为: 0000 0000 0000 0010
* 全部位右移 1 位后为: 0000 0000 0000 0001 (右边的溢出,不要了,左边补上一个0)
* 转化为十进制为 1 。
*/
System.out.println(2>>1); //右移运算符 低位溢出,高位补0
System.out.println(8<<2); //左移运算符 高位溢出,低位补0
System.out.println(8>>>1); //1000
&、^、| 按位运算符
对二进制进行运算
- |(一个以上为1,就为1,否则为0)
- 1010
- 1000
- 1010
- ^(同位相同为0,否则为1)
- 1010
- 1000
- 1010
- &(同为1为1,否则为0)
- 1010
- 1000
- 1000
/*
* 位运算符二进制位运算原理
*/
Integer a = 10;
Integer b =8;
System.out.println(a | b); //1010有1个以上为1,否则为0 0+2+0+8
System.out.println(a ^ b); //0010同位相同 ,为0, 否则为1 0+2+0+0
System.out.println(a & b); //1000同为1,为1,否则为0 0+0+0+8
&与&&、|与||的区别
- a && b //a是false, 不会继续判断b的结果
- a & b //a是false,也会继续判断b的结果
- a || b //a是true,不会继续判断b的结果
- a | b //a是true,也会继续判断b的结果
? : 三目运算符
- 表达式 : 返回值1:返回值2
- 表达式为true,返回值1
- 表达式为false,返回值2
/*
a>b ? a : b true 就输出a的值5, false就输出b的值6
*/
public static void demo1() {
int a = 5;
int b = 6;
System.out.println(a>b ? a : b);
}