单位换算
bit:位 一个二进制数据0或1,是1bit;
byte:字节 1 byte = 8 bit , 存储空间的基本计量单位;
一个英文字符占一个字节 1 字母 = 1 byte = 8 bit;
一个汉字占2个字节 1 汉字 = 2 byte = 16 bit;
支持的数据类型
首先明确一点,Java中的位运算是针对整型的数据类型进行运算的,所以操作数必须是一下五种之一。
数据类型 | 所占位数(bit) |
---|---|
byte | 8 |
short | 16 |
int | 32 |
long | 64 |
char | 16 |
数据存储方式
计算机中存储的数据最终是以二进制存储(补码存储),如int类型的十进制数字10表示为32bit的二进制:
0000 0000 0000 0000 0000 0000 0000 1010
注:数据在计算机中都是以反码形式存在。正数的的原码与反码相同。 有关原码、反码、补码的知识,请看另一个章节原码、反码、补码
位运算符
运算符 | 含义 |
---|---|
& | 按位与(对应位同为1时,才为1,否则全为0) |
| | 按位或(对应位只要有1时,即为1,否则全为0) |
~ | 按位非(对每位进行取反) |
^ | 按位异或(只要对应为不同即为1) |
« | 左移(左移 左边最高位丢弃,右边补齐0) |
» | 右移(最高位是0,左边补齐0;最高为是1,左边补齐1) |
«< | 无符号右移(无论操作数是正数还是负数,高位都是补0) |
按位与 &
规则: 对应位同为1时,才为1,否则全为0(对应位只要有0,全为0,否则为1)
int a = 127;
int b = 128;
System.out.println("127 & 128 的结果是:"+(a & b));
运行结果:
127 & 128 的结果是:0
解析:
127的二进制(补码):00000000 00000000 00000000 01111111
128的二进制(补码):00000000 00000000 00000000 10000000
根据 & 规则结果: 00000000 00000000 00000000 00000000
所以结果为0
按位或 |
规则: 对应位只要有1时,即为1,否则全为0(对应位只有全是0时,结果才是0,否则为1)
int a = 127;
int b = 128;
System.out.println("127 | 128 的结果是:"+(a | b));
运行结果:
127 | 128 的结果是:255
解析:
127的二进制(补码):00000000 00000000 00000000 01111111
128的二进制(补码):00000000 00000000 00000000 10000000
根据 | 规则结果: 00000000 00000000 00000000 11111111
最高为0,为正数,原码补码一样,所以结果为255
按位非 ~
规则: 对每位进行取反
int a = 128;
System.out.println("~128 的结果是:" + ~ a);
运行结果:
~128 的结果是:-129
解析:
128的二进制(补码):00000000 00000000 00000000 10000000
根据 ~ 规则结果: 11111111 11111111 11111111 01111111
最高为1,为负数。
补码:11111111 11111111 11111111 01111111
反码:11111111 11111111 11111111 01111110
原码:10000000 00000000 00000000 10000001
结果为 -129
按位异或 ^
规则: 只要对应为不同即为1。
int a = 127;
int b = 128;
System.out.println("127 ^ 128 的结果是:" + (a ^ b));
运行结果:
127 ^ 128 的结果是:255
解析:
127的二进制(补码):00000000 00000000 00000000 01111111
128的二进制(补码):00000000 00000000 00000000 10000000
根据 | 规则结果: 00000000 00000000 00000000 11111111
最高为0,为正数,原码补码一样,所以结果为255
位移动运算符
左移 «
规则: « :左移 左边最高位丢弃,右边补齐0;
- 左移的规则只记住一点:丢弃最高位,0补最低位
- 如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模
通用格式:
value << num
num : 指要移位值
value : 指移动的位数。
意思是value向左位移num位,左移num位,相当于乘以2^num
例如:
int a = 1;
System.out.println("1 << 2 的结果是:" + (a << 2));
运行结果(图片来自于网络):
1 << 2 的结果是:4
右移 »
规则: »:右移, 最高位是0(正数时),左边补齐0;最高为是1(正数时),左边补齐1,保持为负数;
m»n即相当于m除以2的n次方,得到的为整数时,即为结果。如果结果为小数,此时会出现两种情况:
1 如果m为正数,得到的商会无条件 的舍弃小数位;
2 如果m为负数,舍弃小数部分,然后把整数部分加+1得到位移后的值。
通用格式:
value >> num
num : 指要移位值
value : 指移动的位数。
意思是value向左位移num位,左移num位,相当于除以2^num
例如:
int a = 12;
System.out.println("12 >> 2 的结果是:" + (a >> 2));
运行结果(图片来自于网络,图中稍有错误,其中10应该为12):
1 << 2 的结果是:4
无符号右移 »>
无符号右移»> 与 右移» 的区别就是无论操作数是正数还是负数,高位都是补0
int a = 12;
System.out.println("12 >>> 2 的结果是:" + (a >>> 2));
int b = -12;
System.out.println("-12 >>> 2 的结果是:" + (b >>> 2));
运行结果:
12 >>> 2 的结果是:3
-12 >>> 2 的结果是:1073741821
解析:
12 >>> 2 跟 12 >> 2 过程一样,上面有过程,我们说下 -12 >>> 2
-12的原码: 10000000 00000000 00000000 00001100
-12的二进制(补码): 11111111 11111111 11111111 11110100
右移2位: 11111111 11111111 11111111 11110100
补齐: 0011111111 11111111 11111111 111101
注意这个补齐因为是无符号的,最高位补0,结果为正数
最高为0,为正数,原码补码一样,所以结果为的结果是:1073741821
comments powered by Disqus