位运算是针对底层操作的,在C语言中比较常见,但是在java 中见得就比较少了,
但是能用到位运算的地方坚决用位运算。
输出一个整数的 2进制:
System.out.println(Integer. toBinaryString(a));
在java 中
int 类型的整数是 32位的
short 类型的整数是 16位的
long 类型的整数是 64位的
short 类型的整数是 8位的
关于 负数:
int a = -1;
System.out.println("-1 = "Integer.toBinaryString(a));
输出:
-1 = 1111 1111 1111 1111 1111 1111 1111 1111
0 = 0000 0000 0000 0000 0000 0000 0000 0000
1000 0000 0000 0000 0000 0000 0000 0000 最小的负整数数 -2147483648
0111 1111 1111 1111 1111 1111 1111 1111 最大的正整数数 2147483647
-18 = 1111 1111 1111 1111 1111 1111 1110 1110
最高为1 则为负数,java 中没有什么符号型 和无符号型的 整数什么的。
可以说都是有符号型的。
int 型 2的32位 数 一般为正整数 一般为负整数
正整数是在
0000 0000 0000 0000 0000 0000 0000 0000 0的基础上加某数
负数是在
1111 1111 1111 1111 1111 1111 1111 1111 -1的基础上减某数
1111 1111 1111 1111 1111 1111 1111 1110 -1-1 = -2
位运算的操作符有 :
& | ~ ^ >> << >>>
且 或 非 异或 右移 左移 无符号右移
同时 &= |= ^= >>= <<= >>>= 都是合法的。 ~= 不合法 ~ 是一元操作符 所有不行
& 且运算:
要两位都为1 &运算的结果在位于
1&
1 = 1
0&
1 =0
010010 &
100111
= 000010
| 或运算:
两位只要一位为1 结果就为1
1|1 = 1
1|0 = 1
0|0 = 0
010010 |
100111
= 110111
^ 亦或运算:
两位 一个1 一个0 就过就为1
0^0 = 0
1^1 = 0
0^1 = 1
010010 ^
100111
= 110101
~ 非运算:
1 变0 ,0 变1
~1 = 0
~0 = 1
int a = 18;
int b = ~a;
System.out.println("a:"+Integer. toBinaryString(a));
System. out.println("b:"+Integer. toBinaryString(b));
输出:
a: 10010
b:11111111111111111111111111101101
int 类型的数据有32位,所以前面的0 经过非运算都变成了 1
<< 左移
普通正整数的左移
int a = 18;
int b = a<<2;
System.out.println(a+ " = " +Integer.toBinaryString(a));
System.out.println(b+ " = " +Integer.toBinaryString(b));
输出:
18 = 10010
72 = 1001000
着实是向左移动了2位, 同时 18*2*2 = 74
向左移多少为代表 该数 乘以 2的多少次方
so:
int b = a*8;
可以写成:
int b = a <<3
来看看 最大正整数的左移:
0111 1111 1111 1111 1111 1111 1111 1111 最大的正整数数 2147483647
左移两位后
1111 1111 1111 1111 1111 1111 1111 1100 -4
负数的左移:
int a = -4;
int b = a<<2;
System.out.println(a+ " =\t" +Integer.toBinaryString(a));
System.out.println(b+ " =\t" +Integer.toBinaryString(b));
输出:
-4 = 11111111111111111111111111111100
-16 = 11111111111111111111111111110000
和正数一样 没有什么区别 直接向左移 低位补0 -4 *2*2 = -16 也是乘以2 的2 次方
最小的整数:
1000 0000 0000 0000 0000 0000 0000 0000 最小的负整数数 -2147483648
int a = -2147483648;
int b = a<<2;
System.out.println(a+ " =\t" +Integer.toBinaryString(a));
System.out.println(b+ " =\t" +Integer.toBinaryString(b));
输出:
-2147483648 = 10000000000000000000000000000000
0 = 0
向左移2位 则每个位都变成0
左移就是 二进制 直接 左移 然后再低位补0 与正负 与否无关
>> 右移
正整数的右移:
int a = 18;
int b = a>>2;
System.out.println(a+ " =\t" +Integer.toBinaryString(a));
System.out.println(b+ " =\t" +Integer.toBinaryString(b));
输出:
18 = 10010
4 = 100
向右移两位 18 后面那两位 10 直接给整没了。
最大正整数 右移:
int a = 2147483647;
int b = a>>2;
System.out.println(a+ " =\t" +Integer.toBinaryString(a));
System.out.println(b+ " =\t" +Integer.toBinaryString(b));
输出:
2147483647 = 1111111111111111111111111111111
536870911 = 11111111111111111111111111111
直接右移 两位
负数的右移:
int a = -4;
int b = a>>2;
System.out.println(a+ " =\t" +Integer.toBinaryString(a));
System.out.println(b+ " =\t" +Integer.toBinaryString(b));
输出:
-4 = 11111111111111111111111111111100
-1 = 11111111111111111111111111111111
向右移 把-4 后面的两个0 给挤掉了,同时在 高位补1
最小负数的右移:
int a = -2147483648;
int b = a>>2;
System.out.println(a+ " =\t" +Integer.toBinaryString(a));
System.out.println(b+ " =\t" +Integer.toBinaryString(b));
输出:
-2147483648 = 10000000000000000000000000000000
-536870912 = 11100000000000000000000000000000
也是直接向右移 高位 补1
右移: 先直向右移动 然后正数在高位 补0
负数在高位 补1
>>> 无符号的右移
就是不管是整数还是负数
右移 然后再高位补0:
例:
int a = -1;
int b = a>>>2;
System.out.println(a+ " =\t" +Integer.toBinaryString(a));
System.out.println(b+ " =\t" +Integer.toBinaryString(b));
输出:
-1 = 11111111111111111111111111111111
1073741823 = 111111111111111111111111111111
直接右移 然后找高位补 0