【问题标题】:Divide two integers without using multiplication, division and mod operator in java在java中不使用乘法,除法和mod运算符将两个整数相除
【发布时间】:2019-06-01 03:40:02
【问题描述】:

我写了一段代码,在将两个数相除后求商,但没有使用乘法、除法或 mod 运算符。

我的代码

public int divide(int dividend, int divisor) {

    int diff=0,count=0;
    int fun_dividend=dividend;
    int fun_divisor=divisor;
    int abs_dividend=abs(dividend);
    int abs_divisor=abs(divisor);

    while(abs_dividend>=abs_divisor){
        diff=abs_dividend-abs_divisor;

        abs_dividend=diff;
        count++;

    }

    if(fun_dividend<0 && fun_divisor<0){
        return count;
    }
    else if(fun_divisor<0||fun_dividend<0) {
        return (-count);
    }

    return count;

}

我的代码通过了诸如除数=-1、除数=1 或除数=1 和除数=-1 之类的测试用例。但它不能通过像除数 = --2147483648 和除数 =-1 这样的测试用例。但是,当两个输入均为负数时,我有一个 if 语句。

  if(fun_dividend<0 && fun_divisor<0){
        return count;
    }

当我的输入为 -2147483648 和 -1 时,它返回零。我调试了我的代码,发现它无法到达 while 循环的内部语句。它只是检查while循环并终止并执行

 if(fun_dividend<0 && fun_divisor<0){
        return count;
    }

很明显,两个输入都是负数,所以我使用Math.abs 函数将它们设为正数。但是当我尝试查看变量 abs_dividend 和 abs_divisor 的值时,它们会显示负值。

Integer max 可以取 9 位数字。那么我怎样才能通过这个测试用例呢?根据这个测试用例,除数是一个 10 位数字,对整数范围无效。

根据测试用例,我得到的输出应该是 2147483647。

我该如何解决这个错误?

提前谢谢你。

【问题讨论】:

    标签: java function if-statement while-loop mod


    【解决方案1】:

    尝试如下使用位操作:

    public static int divideUsingBits(int dividend, int divisor) {
            // handle special cases
            if (divisor == 0)
                return Integer.MAX_VALUE;
            if (divisor == -1 && dividend == Integer.MIN_VALUE)
                return Integer.MAX_VALUE;
    
            // get positive values
            long pDividend = Math.abs((long) dividend);
            long pDivisor = Math.abs((long) divisor);
    
            int result = 0;
            while (pDividend >= pDivisor) {
                // calculate number of left shifts
                int numShift = 0;
                while (pDividend >= (pDivisor << numShift)) {
                    numShift++;
                }
    
                // dividend minus the largest shifted divisor
                result += 1 << (numShift - 1);
                pDividend -= (pDivisor << (numShift - 1));
            }
    
            if ((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0)) {
                return result;
            } else {
                return -result;
            }
        }
    

    【讨论】:

    • 为什么这行是result += 1 &lt;&lt; (numShift - 1); 而不仅仅是result+= (numShift-1)
    【解决方案2】:

    我是这样解决的。优先考虑数据类型long 而不是int 在左移时有可能溢出的地方。从一开始就处理边缘情况,以避免在此过程中修改输入值。该算法基于我们在学校使用的除法技术。

    public int divide(int AA, int BB) {
        // Edge case first.    
        if (BB == -1 && AA == Integer.MIN_VALUE){
            return Integer.MAX_VALUE;   // Very Special case, since 2^31 is not inside range while -2^31 is within range.
        }
        long B = BB;
        long A = AA;
    
        int sign = -1;
        if ((A<0 && B<0) || (A>0 && B>0)){
            sign = 1;
        }
        if (A < 0) A = A * -1;
        if (B < 0) B = B * -1;
    
        int ans = 0;
        long currPos = 1; // necessary to be long. Long is better for left shifting.
        while (A >= B){
            B <<= 1; currPos <<= 1;
        }
        B >>= 1; currPos >>= 1;
        while (currPos != 0){
            if (A >= B){
                A -= B;
                ans |= currPos;
            }
            B >>= 1; currPos >>= 1;
        }
        return ans*sign;
    }
    

    【讨论】:

    • OP 要求不要使用乘法运算符
    【解决方案3】:

    用调试器运行,发现abs_dividend 是-2147483648。

    那么while (abs_dividend &gt;= abs_divisor) { 中的比较为假,count 永远不会增加。

    原来解释在Math.abs(int a)的Javadoc中:

    请注意,如果参数等于 Integer.MIN_VALUE 的值,即最负的可表示 int 值,则结果是相同的值,即为负。

    大概是因为Integer.MAX_VALUE是2147483647,所以没有办法用int来表示正数2147483648。 (注意:2147483648 将是Integer.MAX_VALUE + 1 == Integer.MIN_VALUE

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-22
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-12
      相关资源
      最近更新 更多