Java利用位运算表示加减乘除
Java中的位运算
位运算符主要用来对操作数二进制的位进行运算。按位运算表示按每个二进制位(bit)进行计算,其操作数和运算结果都是整型值。
Java 语言中的位运算符分为位逻辑运算符和位移运算符两类
位逻辑运算符
位逻辑运算符包括: &(与)、|(或)、~(非)和 ^(异或)
与运算符 &
运算规则是:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位同时为 1,那么计算结果才为 1,否则为 0。(任何数与0想与都为0)
或运算符 |
运算规则是:参与运算的数字,低位对齐,高位不足的补零。如果对应的二进制位只要有一个为 1,那么结果就为 1;如果对应的二进制位都为 0,结果才为 0。
非运算符 ~
运算规则是:只对一个操作数进行运算,将操作数二进制中的 1 改为 0,0 改为 1。
异或运算符 ^
运算规则是:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位相同(同时为 0 或同时为 1)时,结果为 0;如果对应的二进制位不相同,结果则为 1。
位移运算符
位移运算符用来将操作数向某个方向(向左或者右)移动指定的二进制位数。
左移运算符 <<
左移 << 其实很简单,也就是说丢弃左边指定位数,右边补0。
右移运算符 >>
右移运算符>>的运算规则也很简单,丢弃右边指定位数,左边补上符号位。
无符号右移 >>>
右移运算符>>的运算规则也很简单,丢弃右边指定位数,左边补上0。
利用位运算表示加减乘除
加法
//位运算表示加法(非递归)
public static int add(int a, int b) {
// a + b = carry + sum
//与运算可以表示进位
int carry = (a & b) << 1;
//异或运算表示本位
int sum = a ^ b;
//当进位为0的时候本位就等于运算结果
while (carry != 0) {
//a表示本位
a = sum;
//b表示进位
b = carry;
carry = (a & b) << 1;
sum = a ^ b;
}
return sum;
}
//位运算表示加法(递归)
public static int addByRecur(int a, int b) {
if (b == 0) {
return a;
}
return addByRecur((a ^ b), (a & b) << 1);
}
减法
//位运算表示减法
public static int subtract(int a, int b) {
//由于a-b=a+(-b)
//在位运算中求一个数的相反数只需要: 对这个数按位取反再+1 -b=~b+1
return add(a, (~b) + 1);
}
乘法
//位运算表示乘法
public static int mul(int a, int b) {
//乘法相当于对有b个a相加
//先算绝对值,再算正负数
int absA=Math.abs(a);
int absB=Math.abs(b);
int sum = absA;
do {
// 累加a
sum = add(sum, a);
} while ((absB = subtract(absB, 1)) != 1);
//判断是正数还是负数
if((a^b)<0){
return (~sum)+1;
}else{
return sum;
}
}
public static int mulNice(int a,int b){
int res=0;
while(b!=0){
if((b&1)!=0){
res=add(res,a);
}
a=a<<1;
b=b>>>1;
}
return res;
}
除法
public static int preDivide(int a,int b){
//先算绝对值,再算正负数
int absA=Math.abs(a);
int absB=Math.abs(b);
int res=divide(absA,absB);
//判断是正数还是负数
//使用异或运算,如果符号位都是1(两个负数)或者都是0(两个正数),结果都是正数,否则结果是负数
if((a^b)<0){
return (~res)+1;
}else{
return res;
}
}
public static int divide(int a,int b){
//a/b也就是求a可以由多少个b组成。求a能减去多少个b,做减法的次数就是除法的商。
int res=0;
if(a<b){
return 0;
}else{
return divide((a-b),b)+1;
}
}
测试
public static void main(String[] args) {
//非递归的加法
System.out.println(add(23, 56)); //79
System.out.println(add(23, -10)); //13
//递归的加法
System.out.println(addByRecur(23, 56)); //79
System.out.println(addByRecur(23, -10)); //13
//减法
System.out.println(subtract(100, 30)); //70
//乘法
System.out.println(mul(23, 4)); //92
System.out.println(mul(23, -4)); //-92
System.out.println(mulNice(23, 4)); //92
System.out.println(mulNice(23, -4)); //-92
System.out.println(mulNice(-23, -4)); //92
//除法
System.out.println(preDivide(10,2)); //5
System.out.println(preDivide(10,3)); //3
System.out.println(preDivide(10,-3)); //-3
System.out.println(preDivide(-10,-3)); //3
}