使用按位运算符除以两个整数

时间:2015-11-19 23:22:24

标签: java data-structures bit-manipulation bitwise-operators

我必须通过使用按位运算符来划分两个数字。我的代码如下:

public class Solution {
    public int divide(int dividend, int divisor) {
        int c = 0, sign = 0;
        if (dividend < 0) {
            dividend = negate(dividend);
            sign^=1;
        }
        if (divisor < 0) {
            divisor = negate(divisor);
            sign^=1;
        }
        if ( divisor != 0){
           while (dividend >= divisor){
                dividend = sub(dividend, divisor);
                c++;
            } 
        }

        if (sign == 1){
            c = negate(c);
        }
        return c;
    }

    private int negate(int number){
        return add(~number,1);
    }
    private int sub(int x, int y){
        return add(x,negate(y));
    }
    private int add(int x, int y){
        while ( y != 0){
          int carry = x&y;
          x = x^y;
          y = carry << 1;
        }
        return x;
    }
}

我在运行代码时遇到超时异常:

Last executed input:
2147483647
1

我在代码中添加了一个额外的检查:

if (divisor == 1){
    return dividend;
}

然后再次运行代码,我得到一个像这样的超时异常:

Last executed input:
2147483647
2

你可以帮我解决代码出错的问题吗?

2 个答案:

答案 0 :(得分:0)

由于您正在使用算术运算的天真实现,我认为它只需要太长时间,因为它必须进行大约10亿次减法,每次减法平均为16次迭代。因此,如果每个内部步骤需要1个周期,那么在3GHz CPU上大约需要5秒钟。但是因为它显然需要更多,特别是考虑到它在java中,我会说你很容易期望像1分钟的运行时间。也许java会对您运行它的环境进行超时检查。

我必须承认我没有彻底验证您的代码,并认为它在算法方面正常工作。

答案 1 :(得分:0)

想想long division是如何运作的,我们在学校学到的所有分工的纸笔方法。

当然我们已经在10号基础上学到了它,但是有没有理由为什么相同的算法在基数2中不起作用?

不,事实上它更容易,因为当您为每个数字执行除法步骤时,如果被除数以上的被除数大于或等于除数,则结果为1 ,否则为0。

并且移除除数和结果也是开箱即用的。