概述
前一篇文章写了位运算的基本概念和使用方法,这次让我来学习一下日常编程里面所用到的位运算。
1 获取int所能表示的最大整数
- 用 -1 无符号右移1位 :-1>>>1
- ~(1 << 31)
- (1 << -1)-1
- (~(1 << -1)
- 任何数左移(右移)32的倍数位等于该数本身。
- 在位移运算中 a >> b 的计算中,若b为正数,则实际移动位数为b%32,若b为负数,则为(b%32 + 32),左移一样。左移是乘以2的幂,对应着右移则是除以2的幂。
- 右移高位补符号位,地位截取。无符号右移高位补零,地位溢出截取。
- 左移高位溢出截取,地位补零。
2 符号的实际含义
Java整型数据类型有:byte、char、short、int、long。要把它们转换成二进制的形式,必须明白他们各占几个字节。我们都知道,一个字节占8位。
3不用临时变量交换两个整数
public void swap(int x , int y){
x ^= y;
y ^= x;
x ^= y;
}
所有公式为:b^(a^b)=a
任何数异或本身结果为零.且有定理a^b=b^a。异或是一个无顺序的运算符,则b^a^b=b^b^a,结果为0^a。
零异或任何数等于任何数
异或0具有保持的特点,而异或1具有翻转的特点
根据上面公式我们可以推到出以下公式。
- a ^ a =0
- a ^ b =b ^ a
- a ^b ^ c = a ^ (b ^ c) = (a ^ b) ^ c;
- d = a ^b ^ c 可以推出 a = d ^ b ^ c.
- a ^ b ^a = b.
4 判断一个数a的奇偶性
公式:n&1 == 1?”奇数”:”偶数”
奇数的最低位为1 ,偶数最低位为0,所以与运算符必须是对应位都是1才为1 ,根据这个特性就可以判断了。
5 计算绝对值
int abs( int x )
{
int y;
y = x >> 31;
return (x^y)-y; //or: (x+y)^y
}
1.任何正数右移31后只剩符号位0,最终结果为0;任何负数右移31后也只剩符号位1,溢出的31位截断,空出的31位补符号位1,最终结果为-1。右移31操作可以取得任何整数的符号位。所以 x >> 31 ,x为正等于0,x为负等于-1。
2.使用位运算取绝对值的思路:若a为正数,则不变,需要用异或零保持的特点;若a为负数,a的绝对值的二进制,然后取反加一位a的补码,然后异或-1 在减 -1就等于a的绝对值。
6 判断一个整数是不是2的幂,对于一个数 x >= 0,判断他是不是2的幂
boolean power2(int x)
{
return ((x&(x-1))==0)&&(x!=0);
}
7 x 的 相反数 表示为 (~x+1)
8 取模运算转化成位运算 (在不产生溢出的情况下)
a % (2^n) 等价于 a & (2^n - 1)
9 乘法运算转化成位运算 (在不产生溢出的情况下)
a * (2^n) 等价于 a < < n
10 除法运算转化成位运算 (在不产生溢出的情况下)
a / (2^n) 等价于 a>> n