c - 除两个整数 [leetcode] 使用 unsigned Short 时发生移位错误

标签 c

描述如下:

Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.
Return the quotient after dividing dividend by divisor.
The integer division should truncate toward zero.

  • Both dividend and divisor will be 32-bit signed integers.
  • The divisor will never be 0.
  • Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]. For the purpose of this problem, assume that your function returns 2^31 − 1 when the division result overflows.

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

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 提到的,我不知道他为什么删除该评论。

左移有符号整数是未定义的行为。并且将 unsignedshort 移位超过 16 也是未定义的,因为 unsignedshort 是 16 位。所以我必须处理这些边缘。

关于c - 除两个整数 [leetcode] 使用 unsigned Short 时发生移位错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55587802/

相关文章:

c - C 编程中的结构指针有问题

c++ - 为什么我在 clrscr(); 中遇到错误它说未定义?

c - 不返回字符串。这个程序将 123 这样的数字转换为 "One Two Three"这样的单词,为什么最后我什么也没有得到?

检查结构数组的 NULL

c - C 如何计算 sin() 和其他数学函数?

c - 想要确定两个单独的 gem 中使用了哪个函数

c - 删除 C 中的最后一个字符

c - 如何从前一个变量中获取多个 scanf 输入

c++ - Windows命令提示符中的彩色文本一行

c++ - Makefile:无规则可作为目标