一、常见的位运算使用场景
注意:位运算按照整数的二进制位进行计算,二进制数最高位(最左边数字)为符号位,最高位为0表示正数,最高位为1表示负数
-
移位运算 << 或 >>
名称 运算规则 使用场景 举例 << 左移运算符 对整数n进行左移运算,等同于将整数n放大
倍,m为位移数
n<<1 :计算整数n的二倍;
n=3
n<<1 等同于
n
= 3
=6
n<<2 等同于
n
= 3
=12
>> 右移运算符 对整数n进行右移运算,等同于将整数缩小 倍,m为位移数
n>>1 :计算整数n的一半; n=12
n>>1 等同于 n
= 12
=6
n>>2 等同于 n
= 12
=3
简记:左移执行乘法,右移执行除法
程序为:
class Main {
public static void main(String[] args) {
int a=3,b=12,a1,a2,b1,b2;
//定义a,b,a1,a2,b1,b2为整数类型;a、b分别赋初值为值3和12;其它默认初值为0
//3的二进制表示为00000000 00000000 00000000 0000000011;
//12的二进制表示为00000000 00000000 00000000 0000001100;
//0的二进制表示为00000000 00000000 00000000 0000000;
a1=a<<1;//a1为a进行左移一位的运算结果
//3左移一位的二进制表示为00000000 00000000 00000000 0000000110,
//转换成十进制结果为6
a2=a<<2;//a2为a进行左移两位的运算结果
//3左移两位的二进制表示为00000000 00000000 00000000 0000001100,
//转换成十进制结果为12
b1=b>>1;//b1为b进行右移一位的运算结果
//12右移一位的二进制表示为00000000 00000000 00000000 0000000110,
//转换成十进制结果为6
b2=b>>2;//b1为b进行右移两位的运算结果
//12右移两位的二进制表示为00000000 00000000 00000000 0000000011,
//转换成十进制结果为3
System.out.println("整数a左移一位的结果为:a1="+a1);
System.out.println("整数a左移两位的结果为:a2="+a2);
System.out.println("整数b右移一位的结果为:b1="+b1);
System.out.println("整数b右移两位的结果为:b2="+b2);
}
}
运行结果为:
-
与运算 &
与运算规则:两个数的二进制对应位数字同时为1,结果才为1
整数 对应二进制数 2 00000000 00000000 00000000 00000010 3 00000000 00000000 00000000 00000011 2&3 00000000 00000000 00000000 00000010(转换成十进制结果为2)
程序为:
class Main {
public static void main(String[] args) {
int a=2,b=3,c;//定义整数a,b,c;a,b分别赋予初值为2和3;c默认值为0
c=a&b;//c为a与b进行与运算的结果
System.out.println("整数a与b进行与运算的结果c为:c="+c);
}
}
运行结果为:
与运算使用场景 判断奇偶数 求平均值(防止溢出) a&1==0 偶数 a&1==1 奇数 (x&y)+((x^y)>>1)(^为异或运算符,下面会讲到)
判断奇偶数程序为:
class Main {
public static void main(String[] args) {
int a=2;//定义一个偶数的整数,赋值为2
int b=3;//定义一个奇数的整数,赋值为3
int c,d;//定义两个整数,默认初值为0
c = a & 1 ;
d = b & 1 ;
System.out.println("偶数a与1做与运算的结果为c="+c);
System.out.println("奇数b与1做与运算的结果为d="+d);
}
}
运行结果为:
判断奇偶数原理如下:1的二进制为00000000 00000000 00000000 00000001,是奇数;
一个偶数的二进制最右边位数一定是为0;
二进制相同位数同时为1时,结果才为1;
若一个偶数与1做与运算,结果的二进制数的数字一定为0
若一个奇数与1做与运算,结果的二进制数的数字一定为1
求平均值(防止溢出)程序为:
class Main {
public static void main(String[] args) {
int x = 2 , y = 4 , z ;//定义整数x,y,z;x,y的初始值分别为2和4,z默认为0
z = ( x & y ) + ( ( x ^ y) >> 1 ) ;//利用位运算方法求x和y的平均值z
System.out.println("x和y的平均值z="+z);
}
}
运行结果为:
-
或运算 |
或运算规则:两个数的二进制对应位数字只要有一个为1,结果就为1
整数 对应二进制数 2 00000000 00000000 00000000 00000010 3 00000000 00000000 00000000 00000011 2 | 3 00000000 00000000 00000000 00000011(转换成十进制结果为3)
程序为:
class Main {
public static void main(String[] args) {
int a=2,b=3,c;//定义整数a,b,c;a,b分别赋予初值为2和3;c默认值为0
c=a | b;//c为a与b进行或运算的结果
System.out.println("整数a与b进行或运算的结果c为:c="+c);
}
}
运行结果为:
-
非运算 ~
非运算规则:整数的二进制位0与1互换(0变成1,1变成0)
整数 对应二进制数 2 00000000 00000000 00000000 00000010 ~2 111111111 111111111 111111111 111111101(转换成十进制数字为 -3)
程序为:
class Main {
public static void main(String[] args) {
int a=2,c;//定义整数a,c,a赋予初值为2,c默认值为0
c= ~a;//c为a进行非运算的结果
System.out.println("整数a进行非运算的结果c为:c="+c);
}
}
运行结果为:
-
异或运算 ^
异或运算规则:两个数的二进制对应位数字不同,结果就为1
整数 对应二进制数 2 00000000 00000000 00000000 00000010 3 00000000 00000000 00000000 00000011 2 ^ 3 00000000 00000000 00000000 00000001(转换成十进制结果为1)
程序为:
class Main {
public static void main(String[] args) {
int a=2,b=3,c;//定义整数a,b,c;a,b分别赋予初值为2和3;c默认值为0
c=a ^ b;//c为a与b进行异或运算的结果
System.out.println("整数a与b进行异或运算的结果c为:c="+c);
}
}
运行结果为:
异或运算使用场景:进行两个数的交换
如:a=2,b=3;通过三次异或运算【a=a^b;b=a^b;a=a^b】,可以得到a=3,b=2
程序为:
class Main {
public static void main(String[] args) {
int a=2,b=3;//定义整数a,b,c;a,b分别赋予初值为2和3;
//a与b做三次异或运算
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println("整数a为:a="+a);
System.out.println("整数b为:b="+b);
}
}
运行结果为:
二、整数类型运算时的类型溢出问题,产生原因以及解决办法
整数类型 int型 进行计算时的类型溢出问题 产生原因 解决办法 整数存在范围限制(整数范围为 -2147483648
~2147483647)计算结果超出这个范围,就会产生溢出,这个溢出不会出错,只是结果比较奇怪
方法一:int型进行类型转换成 long型,long型可表示的整形范围更大,结果就不会溢出了
【 long型范围为 -9223372036854775808~9223372036854775807 】
方法二:使用BigInteger,BigInteger不会有范围限制(但相对于long型的运算,计算速度降低),BigInteger表示任意大小的整数,BigInteger做运算,只能使用实例方法
程序为:
import java.math.BigInteger;
class Main {
public static void main(String[] args) {
int a = 2147483647;//定义整数a,赋值为int类型最大值
int b = 14;//定义整数b,赋值为14
int c = a+b;//计算a与b的和c[int型]
System.out.println("[int型]计算a与b的和c="+c);//结果为负值,不正确;
//因为类型溢出了
//解决类型溢出问题
//方法一:int型进行类型转换成 long型
long d = (long)a+b;//计算a与b的和c[long型]
System.out.println("[long型]计算a与b的和d="+d);//结果正确
//方法二:使用BigInteger
BigInteger e = new BigInteger("2147483647");//定义整数e,与a大小一致
BigInteger f = new BigInteger("14");//定义整数f,与b大小一致
System.out.println("[BigInteger型]计算e与f的和,结果为"+e.add(f));//结果正确
}
}
运行结果为:

三、浮点类型运算时的精度丢失问题,产生原因以及解决办法
浮点类型运算时的精度丢失问题 产生原因 解决办法 由于浮点数属于小数范围,小数换算成二进制会出现无限循环小数,计算机不能显示出无限位数的小数,只能取近似值显示,就会造成浮点数无法精确表示的情况,就会出现精度丢失问题 使用BigDecimal,BigDecimal与BigInteger类似,它可以表示一个任意大小且精度完全准确的浮点数
程序为:
import java.math.BigDecimal;//导入java.Math.BigDecimal包
class Main {
public static void main(String[] args) {
double a = 1.0;//定义浮点数a=1.0
double b = 0.9;//定义浮点数b = 0.9
double c = a-b;//定义浮点数a与b的差c
System.out.println("浮点数a与b的差为c="+c);//精度丢失,结果不正确
BigDecimal d = new BigDecimal("1.0");//定义BigDecimal类型浮点数d,与a值相同
BigDecimal e = new BigDecimal("0.9");//定义BigDecimal类型浮点数e,与b值相同
System.out.println("浮点数d与e的差为: "+d.subtract(e));//结果正确
}
}
运行结果为: