разделить два целых [leetcode] ошибка смещения при использовании unsigned short - PullRequest
0 голосов
/ 09 апреля 2019

вот описание:

С учетом двух целых чисел: делить и делить, делить два целых числа без использования умножения, деления и оператора мод.
Вернуть коэффициент после деления дивиденда на делитель.
Целочисленное деление должно усекаться до нуля.

  • И дивиденды, и делители будут 32-разрядными целыми числами со знаком.
  • Делителем никогда не будет 0.
  • Предположим, мы имеем дело со средой, которая может хранить целые числа только в диапазоне 32-разрядных целых чисел со знаком: [−2 ^ 31, 2 ^ 31 - 1]. В целях этой проблемы предположим, что ваша функция возвращает 2 ^ 31 - 1, когда результат деления переполняется.

Я пишу решение, но получил left shift of x by y places cannot be represented in type 'int' из строки s22 = s2 << curr;, в то время как я просто использую unsigned short. Я не знаю почему?

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.

Ответы [ 2 ]

0 голосов
/ 09 апреля 2019

для этого вопроса у нас есть альтернативный метод. пожалуйста, пройдите

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);
}
0 голосов
/ 09 апреля 2019

как упомянул KamilCuk, я не знаю, почему он удалил комментарий.

Сдвиг влево со знаком int - неопределенное поведение.и смещение короткого знака без знака больше 16 также не определено, так как короткий без знака равен 16 битам.Поэтому я должен разобраться с этими краями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...