使用无符号短整型时除以两个整数 [leetcode] 移位错误



这是描述:

给定两个整数除法和

除数,在不使用乘法、除法和 mod 运算符的情况下除以两个整数。
除以除数后返回商。
整数除法应截断为零。

  • 数和除数都将是 32 位有符号整数。
  • 除数永远不会为 0。
  • 假设我们正在处理一个只能存储 32 位有符号整数范围内的整数的环境:[−2^31, 2^31 − 1]。出于此问题的目的,假设您的函数在除法结果溢出时返回 2^31 − 1。

我写了一个解决方案,但从第 s22 = s2 << curr;left shift of x by y places cannot be represented in type 'int',而我只使用无符号的短。我不知道为什么?

int divide(int dividend, int divisor) {
    bool flag = false;
    if (divisor == 0 || (dividend == INT_MIN && divisor == -1)) {
        return INT_MAX;
    }
    unsigned short p1 = 0,  p2 = 0, s1 = 0, s2 = 0;
    if (divisor == INT_MIN) return 0;
    if (dividend == INT_MIN) {
        dividend = 0;
        flag = !flag;
        p1 = 0x8000;
        p2 = 0x0;
    }
    if(dividend < 0) {
        flag = !flag;
        dividend = ~dividend + 1;
    }
    if(dividend != 0) {
        p1 = dividend >> 16;
        p2 = dividend & 0xffff;
    }
    if(divisor < 0) {
        flag = !flag;
        divisor = ~divisor + 1;
    }
    s1 = divisor >> 16;
    s2 = divisor;
    int ret = 0;
    unsigned short curr = 31;
    while(curr > -1) {
        unsigned short p11 = p1 >> curr;
        unsigned short p22, s11, s22;
        s22 = s2 << curr;
        if (curr > 15) {
            p22 = p1 >> (curr - 16);
            s11 = s2 << (curr - 16);
        } else {
            p22 = p2 >> curr | (p1 << (16 - curr));
            s11 = (s1 << curr) | (s2 >> (16 - curr));
        }
        if (p11 > s1 || (p11 == s1 && p22 >= s2)) {
            ret = (ret<<1) | 0x01;
            if (p2 < s22) {
                int tmp = p2 | 0x10000;
                p2 = tmp - s22;
                p1 = p1 - 1 - s11;
            }
            else {
                p2 -= s22;
                p1 -= s11;
            }
        }
        else {
            ret = ret << 1;
        }
        curr--;
    }
    return flag ? ~ret + 1 : ret;
}

我避免使用任何大于 int 的数据类型。

正如KamilCuk提到的,我不知道他为什么删除了评论。

左移有符号 int 是未定义的行为。并且移位无符号短 大于 16 也是未定义的,因为无符号短是 16 位。所以我必须处理这些边缘。

对于这个问题,我们有替代方法。 请通过

int dividend, divisor, quotient, reminder;
while(1)
{
    printf("Enter no:n");
    scanf("%d %d",&dividend,&divisor);
    for(reminder = dividend, quotient = 0;divisor <= reminder;)
    {
        reminder = reminder - divisor;
        quotient = quotient + 1;         
    }
    printf("Quotien: %d Reminder: %d",quotient,reminder);
}

最新更新