看集合扩容时能经常看到位运算,所以翻出来复习一下
三者是计算机存储数据的不同形式,计算机用补码存储数据。而且计算机利用这三者可以用加法实现减法
反码:
1+(-1) = [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0
反码出现了 [0000 0000] 原和 [1000 0000] 原两个编码表示正负0,补码出现了
补码:
1+(-1) = [0000 0001]补 + [1111 1111]补 = [0000 0000]补 = [0000 0000]原
解决了正负0编码不同问题
位运算是对底层2进制操作的
符号 | 描述 | 运算规则 |
---|---|---|
& | 与 | 两个都为1,结果才为1 |
| | 或 | 两个都为0,结果才是0 |
^ | 异或 | 同0异1 |
~ | 取反 | 0变1,1变0 |
<< | 左移 | 各二进位全部左移若干位,高位丢弃,低位补0。表示2次幂 |
>> | 右移 | 各二进位全部右移若干位,对无符号数,高位补0。表示除2 |
有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) | ||
>>> | 逻辑右移 | 不管符号位,直接右移,补零 |
判断奇偶
// 最末尾为0偶数,1奇数 // 转成二进制,eg:1010 = 2^3 + 0 + 2^1 + 0 = 10偶数,只看最后一位即可因为,2^0 = 1,不是2的倍数 public static void main(String[] args) throws IOException { int a = 4; if( (a & 1) == 0){ System.out.println("偶数"); }else{ System.out.println("奇数"); } }
取模
h & (length-1) // 其实很简单,主要看length // &运算,就算h全部为1,&之后都是看length有1的部分,高位全为0 // 那么最大只能是length,所以范围限定在了length里,比 % 运算快多了 // -1为了符合数组0开始 // 这也是扩容为2次幂的原因,配合取模运算
2次幂(只有一个1,其他位为0)
1---0001 2---0010 4---0100 8---1000
快速幂
int poww(int a,int b){ int res = 1; int base = a; while(b != 0){ if( b & 1 != 0){ // 找到二进制尾数为1的 res *= base; // 结果乘于幂 } base *= base; // 这里呢,一直乘,模拟次幂递增,如果上面为1了,那么这样就会对应到乘于几次幂 b >>= 1; } return res; }
位运算加法
public int Add(int num1,int num2) { while(num2 != 0){ int sum = num1 ^ num2; // 计算有单个1的位(0和0位不用计算了,1和1进位给下面操作了) int carry = (num1 & num2) << 1; // 进位操作 num1 = sum; num2 = carry; } return num1; }
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句