09-Java 中位运算符
你好,我是悦创。本次课,先学:https://bornforthis.cn/posts/21.html。
0. 目录
- 字面值的八进制和十六进制
- 按位运算符
- 位移运算符
- 位运算符不会改变原变量的值
- 位运算符用处
1. 字面值的八进制和十六进制
1.1 以 0 开头的整数为八进制
- 05 就是十进制的 5
- 011就是十进制的 9
1.2 以 0x 开头的整数位十六进制
- 0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F;
0xF
就是十进制的 150x11
就是十进制的 17
public class LiteralNumber {
public static void main(String[] args) {
int a = 05;
int b = 011;
int c = 0xF;
int d = 0x11; // x、X 都可以
System.out.println(a); // 5
System.out.println(b); // 9
System.out.println(c); // 15
System.out.println(d); // 17
}
}
2. 按位运算符【每个二进制的位】
- 按位并(AND):
&
- 按位或(OR):
|
- 按位异或(XOR):
^
【一句话,相异为真 ,运算规则是:两个数转为二进制,然后从高位开始比较,如果相同则为 0,不相同则为 1。】 - 按位取反:
~
储备知识:
- int 有 4 个字节,每个字节有 8 位,一共 32 位。也就是这样的形式: 00000000 00000000 00000000 00000000;
- 32 的二进制是:100000 ,把 32 的二进制放入上面储备知识中得出这样的效果:00000000 00000000 00000000 00100000。当然你也可以缩写成这样的效果:00100000。
- 接下来我们可以进行取反,取反之后为的结果为: 11011111;
- 操作的维度是 bit
public class BitCalc {
public static void main(String[] args) {
// F->15-> 1111
// 二进制的 1111 1000
int a = 0xF8;
// 二进制的 1111 0100
int b = 0xF4;
// 二进制的 1111 1111
int c = 0xFF;
System.out.println(a & b); // 240
System.out.println(a | b); // 252
System.out.println(a ^ b); // 12
System.out.println(~c); // -256
}
}
/* 补充:
a 1111 1000
b 1111 0100
& 1111 0000
| 1111 1100
^ 0000 1100
C 255 > 11111111
~ -255
*/
以我的工作经验来看,Java 中按位运算是比较少的。但是,我们要知道有这样一种操作。这样之后遇到,你就不会一脸懵!在这里,我不推荐你在日后的工作中有使用 **位 **运算符的倾向,当你想到,这个问题可以使用位运算符解决的时候,你再想想有没有更好的,更让人容易理解的方法。当然,如果真没有的话就算了。
3. 位移运算符
推荐先看里面部分内容:https://blog.csdn.net/qq_33254766/article/details/108702875
现代计算机是基于二进制的,我们就来看看,计算机语言中针对二进制的位操作。这里的位操作,也叫作位运算,就是直接对内存中的二进制位进行操作。常见的二进制位操作包括向左移位和向右移位的移位操作,以及“或”“与”“异或”的逻辑操作。「上面已经讲过与或非」下面我们来看位移运算符。
3.1 位移运算符
3.1.1 右移
移位的数字(x) >> 移位量(y)
右移运算是将移动的数字的 二进制位数 按指定 移位量 向右移动,右边低位溢出 y 位则舍弃。左边的空位一律补 0 或者补符号位,这由不同的机器而定。
若移位的数字不带符号位,则左边空位补入的数全部为 0;若是带符号数,则补入的数全部为原数最左边的符号位(正数 0,负数 1)。
PS:
>>
:符号位不动,其余位右移,符号位后边补 0,又称带符号右移「原本正数,那移动之后依然是正数。反之亦然。」- 当负数右移操作时,先对负数的原码求其补码再进行右移操作。
3.1.2 无符号右移
>>>
:符号位一起右移,左边补 0,又称无符号右移 「无符号右移,那带着符号位意味着如果原本是正数,那符号位就是 0。右移之后,左边补 0。那还是正数。如果原本是负数,那无符号右移就会变成正数。」
3.1.3 左移
将移位的数字的 二进制位 全部左移指定的 移位量 移位量由右操作数指定,右操作数必须是非负值,其右边空出的位用 0 填补,高位左移溢出则舍弃该高位。
<<
:左移,右边补 0。左移没有带符号位一说,因为符号位在最左侧。- 换一种方法理解:
num << 1
,左移1位相当于 num 乘以 2 的 1 次方
- 换一种方法理解:
public class BitShift {
public static void main(String[] args) {
// 0x400 to binary 0100 0000 0000
int a = 0x400;
System.out.println(a); // 1024
System.out.println(a >> 1); // 0100 0000 0000 >> 1 -> 0010 0000 0000 to decimalism 512【1024/2】
System.out.println(a >> 2); // 0100 0000 0000 >> 2 -> 0001 0000 0000 to decimalism 256【1024/4】
System.out.println(a << 1); // 0100 0000 0000 << 1 -> 1000 0000 0000 to decimalism 2048【1024*2】
System.out.println(a << 2); // 0100 0000 0000 << 2 -> 0001 0000 0000 0000 to decimalism 4096【1024*4】
System.out.println(a >>> 1); // 0100 0000 0000 >> 1 -> 0010 0000 0000 to decimalism 512【1024/2】
System.out.println(a >>> 2); // 0100 0000 0000 >> 2 -> 0001 0000 0000 to decimalism 256【1024/4】
int b = -0x400;
System.out.println(b); // -1024
System.out.println(b >> 1);
/* -1024
* 原码:1100 0000 0000
* 反码:1011 1111 1111
* 补码:1100 0000 0000
* 右移:1010 0000 0000
* 10 0000 0000 to decimalism 512 result >> -512
*/
System.out.println(b >> 2);
/* 补码:1100 0000 0000
* 右移2:1001 0000 0000 to decimalism -256*/
System.out.println(b << 1);
/* 补码:0000 1100 0000 0000
* 左移1:0001 1000 0000 0000 to decimalism -2048*/
System.out.println(b << 2);
/* 补码:0000 1100 0000 0000
* 左移2:0011 0000 0000 0000 to decimalism -4096*/
System.out.println(b >>> 1); // 了解即可
System.out.println(b >>> 2);
}
}
3.2 位运算符不会改变原变量的值
3.2.1 按位运算符不会改变原本的变量的值
3.2.2 位移运算符不会改变原本的变量的值
public class BitOprtNotChangeVariableValue {
public static void main(String[] args) {
int a = 0x400; // 0100 0000 0000 // 1024
int b = 0xF4;
int c = 0xFF;
System.out.println(a >> 2); // 256
System.out.println(~a); // -1025
/* 原码:0100 0000 0000
* 反码:0011 1111 1111
* 补码:0100 0000 0000
* 取反:1011 1111 1111 逐位取反,包括符位
* 补码减1:1011 1111 1110
* 再取反:1100 0000 0001 -> 取反后的二进制是负数 -> -1025
*/
System.out.println(a | 0x8);
/* a 原码: 0100 0000 0000
* 0x8 原码:0000 0000 1000
* 0100 0000 1000 -> 1032*/
System.out.println(a); // 1024
}
}
3.3 位运算符用处
3.3.1 按位运算符
- 掩码(MASK)
3.3.2 位移运算符
- 高效除以 2
public class BitOprtUsage {
public static void main(String[] args) {
int base = 1;
int is_student_mask = base;
int is_programmer_mask = base << 1; // 0001 -> 0010
int is_driver_mask = base << 2; // 0001 -> 0100
int is_painter_mask = base << 3; // 0001 -> 1000
int data = 5;
boolean isStudent = (data & is_student_mask) != 0; // true
//System.out.println(data & is_student_mask); // 1
/*data: 0101
* is_student_mask: 0001
* 0001 -> 1*/
System.out.println(isStudent);
boolean isProgrammer = (data & is_programmer_mask) != 0;
System.out.println(isProgrammer);
boolean isDriver = (data & is_driver_mask) != 0;
System.out.println(isDriver);
boolean isPainter = (data & is_painter_mask) != 0;
System.out.println(isPainter);
}
}
欢迎关注我公众号:AI悦创,有更多更好玩的等你发现!
公众号:AI悦创【二维码】
AI悦创·编程一对一
AI悦创·推出辅导班啦,包括「Python 语言辅导班、C++ 辅导班、java 辅导班、算法/数据结构辅导班、少儿编程、pygame 游戏开发」,全部都是一对一教学:一对一辅导 + 一对一答疑 + 布置作业 + 项目实践等。当然,还有线下线上摄影课程、Photoshop、Premiere 一对一教学、QQ、微信在线,随时响应!微信:Jiabcdefh
C++ 信息奥赛题解,长期更新!长期招收一对一中小学信息奥赛集训,莆田、厦门地区有机会线下上门,其他地区线上。微信:Jiabcdefh
方法一:QQ
方法二:微信:Jiabcdefh
- 0
- 0
- 0
- 0
- 0
- 0