一、常见位运算使用场景
位运算:是只对整型数据操作的运算方式
常见的位运算有 与(&)、或(|)、异或(^),非(~),左移(<<),右移(>>)
符号 | 说明 | 举例 |
---|---|---|
& | 与 | 将两个二进制数的对应位同时为1时,结果的对应位才为1,否则为0。 |
| | 或 | 将两个二进制数的对应位只要有一个为1,结果的对应位就为1。 |
^ | 异或 | 将两个二进制数的对应位不同的情况下,结果的对应位为1,相同则为0。 |
~ | 非 | 将二进制数的每一位取反,即1变为0,0变为1。 |
<< | 左移 | 将二进制所有位按值向左移动,高位舍弃,低位补 0 |
>> | 右移 | 将二进制数的所有位向右移动指定的位数,右边移出的位丢弃,左边的位根据符号位进行填充。 |
1.判断奇偶数
在二进制中奇数的最低位为1,偶数的最低位为0;因此可以将需要判断的数和1进行与运算,若是结果为1,则该数为奇数;若是结果为0,则该数为偶数。
public class Test07 {
public static void main(String[] args) {
int i = 7;
int ret = i & 1;
System.out.println(ret == 0 ? "为偶数" : "为奇数");
}
}
2.交换元素
根据异或运算的特性,两个二进制对应位相同为0,不同则为1。
//交换a和b
int a = 5; // 0101
int b = 7; // 0111
a = a ^ b; // 0010
b = a ^ b; // 0101
a = a ^ b; // 0111
3.求平均值
可以通过移位运算对数值操作,提高效率;
左移一位(相当于乘以2)右移一位(相当于除以2)
int a = 5;
int b = 7;
int aug = (a+b) >> 1; //结果为6
int sum = (a+b) << 1; //结果为24
4.找出数据中落单的数
俩个相同的数异或结果为0,因此遍历数组使每个数与0进行异或运算 结果就为数组落单的数
public class Test09 {
public static void main(String[] args) {
//找出数组中不成对的数
int[] num = {1,2,3,4,5,4,3,2,1};
int ret = 0;
for(int i = 0;i<num.length;i++) {
ret = ret ^ num[i]; //0001 0011 0000 0100 0001 0101 0110 0100 0101
}
System.out.println(ret);
}
}
5.求二进制中1的个数
一个二进制数 n 例如:n = 10110100 我们可以对其减一 :(n-1) = 10110011 ,使用与运算n&(n-1) = 10110000 就可以消除一个1。 每次循环都会消除一个1,直至n=00000000为止;然后通过计数器就可以得出二进制中1的个数
int a = 180; //二进制
int count = 0; //计数器
while(a>0) {
a = a & (a-1);
count++;
}
System.out.println(count);
二、整数类型运算时的类型溢出问题,产生原因以及解决办法
1.产生原因
由于计算结果超出了该类型所能表示的范围,int类型的范围是-2147483648~2147483647,如果计算结果超出了这个范围就会产生类型溢出;或是在类型转化时比如:long类型的转化为int类型时,也可能会出现类型溢出。
2.解决办法
- 可以使用更大范围的整数类型(BigInteger)来计算
BigInteger big1 = new BigInteger("2147483649");
BigInteger big2 = new BigInteger("2147483648");
BigInteger sum = big1.add(big2);
三、浮点类型运算时的精度丢失问题,产生原因以及解决办法
1.产生原因
因为计算机内部是使用二进制来表示浮点数的,在十进制小数转化为二进制时,会产生无限循环小数,因此结果通常会取其近似值
double a = 0.1;
double b = 0.2;
double sum = a + b;
System.out.println(sum);
结果:
sum = 0.30000000000000004
2.解决办法
使用BigDecimal来计算
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal sum = a.add(b);
结果:
sum = 0.3