位运算--01---两数相除
Posted 高高for 循环
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算--01---两数相除相关的知识,希望对你有一定的参考价值。
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
两数相除
题目:
分析:
除法的意义就在于:求a可以由多少个b组成。那么由此我们可得除法的实现:求a能减去多少个b,做减法的次数就是除法的商。
辅助代码:
加 键 乘
public static int add(int a, int b)
int sum = a;
while (b != 0)
sum = a ^ b;
b = (a & b) << 1;
a = sum;
return sum;
public static int negNum(int n)
return add(~n, 1);
public static int minus(int a, int b)
return add(a, negNum(b));
public static int multi(int a, int b)
int res = 0;
while (b != 0)
if ((b & 1) != 0)
res = add(res, a);
a <<= 1;
b >>>= 1;
return res;
除法逻辑分析
isNeg(int n) 判断一个数是否小于0
public static boolean isNeg(int n)
return n < 0;
正常相除逻辑 c= a/b
a= 2的K次方 * b + 2的(K-n)次方*b +…
最后c = b * ( 2^k + 2^(k-n)+…)
public static int div(int a, int b)
int x = isNeg(a) ? negNum(a) : a;
int y = isNeg(b) ? negNum(b) : b;
int res = 0;
for (int i = 30; i >= 0; i = minus(i, 1))
if ((x >> i) >= y)
res |= (1 << i);
x = minus(x, y << i);
return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
- isNeg(int n) 先全部转成正数来计算
- int是32位,0-31,其中第31位表示符号位,一位一位的去做判断
- (x >> i) >= y , x右移去找能大于等于y的,(等同于y左移小于等于x,不过左移,因为符号位的关系,有安全隐患) --------判断K的值是否存在
- 找到符合条件的位数,记录下来 用res= res | (1 << i); 2的k次方存在,对应位数记录为1
- 然后x减去 y << i
- 循环
return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
a != b 可以转换为 a ^ b
怎么解决系统最小值转绝对值
最小负数 相反数 也是最小负数
分析
public static int divide(int a, int b)
if (a == Integer.MIN_VALUE && b == Integer.MIN_VALUE)
return 1;
else if (b == Integer.MIN_VALUE)
return 0;
else if (a == Integer.MIN_VALUE)
if (b == negNum(1))
return Integer.MAX_VALUE;
else
int c = div(add(a, 1), b);
return add(c, div(minus(a, multi(c, b)), b));
else
return div(a, b);
- a 和 b都是系统最小值,则返回1
- a不是系统最小, b是系统最小值, ,则返回0
- a是系统最小值, b不是
- a也不是 ,b也不是----可以直接用上述div(int a, int b)方法
a是系统最小值, b不是,分2种情况
if (b == negNum(1))
return Integer.MAX_VALUE;
else
int c = div(add(a, 1), b);
return add(c, div(minus(a, multi(c, b)), b));
第一种: 如果a是系统最小值,且b等于-1
计算机底层规定: 系统最小值比系统最大值多1
比如int范围是: -128到127
- 按道理等于系统最大值+1,
- 因为计算机底层不存在,系统最大值+1
- 所以按leetcode规定,返回系统最大值
所以leetcode规定: 系统最小值/-1 =系统最大值
第二种: 如果a是系统最小值,且b不等于-1
那么令a+1去除以b,后面再去补偿
两数相除----总的代码
public class Code03_BitAddMinusMultiDiv
public static int add(int a, int b)
int sum = a;
while (b != 0)
sum = a ^ b;
b = (a & b) << 1;
a = sum;
return sum;
public static int negNum(int n)
return add(~n, 1);
public static int minus(int a, int b)
return add(a, negNum(b));
public static int multi(int a, int b)
int res = 0;
while (b != 0)
if ((b & 1) != 0)
res = add(res, a);
a <<= 1;
b >>>= 1;
return res;
public static boolean isNeg(int n)
return n < 0;
public static int div(int a, int b)
int x = isNeg(a) ? negNum(a) : a;
int y = isNeg(b) ? negNum(b) : b;
int res = 0;
for (int i = 30; i >= 0; i = minus(i, 1))
if ((x >> i) >= y)
res |= (1 << i);
x = minus(x, y << i);
return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
public static int divide(int a, int b)
if (a == Integer.MIN_VALUE && b == Integer.MIN_VALUE)
return 1;
else if (b == Integer.MIN_VALUE)
return 0;
else if (a == Integer.MIN_VALUE)
if (b == negNum(1))
return Integer.MAX_VALUE;
else
int c = div(add(a, 1), b);
return add(c, div(minus(a, multi(c, b)), b));
else
return div(a, b);
以上是关于位运算--01---两数相除的主要内容,如果未能解决你的问题,请参考以下文章