побитовый вопрос - PullRequest
       1

побитовый вопрос

4 голосов
/ 08 июля 2010

если у меня есть int temp = (1 << 31) >> 31. Почему температура становится -1? как мне обойти эту проблему? спасибо

Ответы [ 5 ]

9 голосов
/ 08 июля 2010

Ints подписываются по умолчанию, что обычно означает, что старший бит зарезервирован для указания, является ли целое число отрицательным или нет.Посмотрите дополнение к двум для объяснения того, как это работает.

Вот результат:

[steven@sexy:~]% cat test.c
#include <stdint.h>
#include <stdio.h>

int main(int argc, char **argv[]) {
    uint32_t uint;
    int32_t sint;
    int64_t slong;
    uint = (((uint32_t)1)<<31) >> 31;
    sint = (1<<31) >> 31;
    slong = (1L << 31) >> 31;
    printf("signed 32 = %d, unsigned 32 = %u, signed 64 = %ld\n", sint, uint, slong);
}

[steven@sexy:~]% ./test
signed 32 = -1, unsigned 32 = 1, signed 64 = 1

Обратите внимание, как вы можете избежать этой проблемы, либо используя "unsigned""int (допускает использование всех 32 битов) или переход к большему типу, который вы не переполняете.

5 голосов
/ 08 июля 2010

В вашем случае 1 в вашем выражении является типом со знаком - поэтому, когда вы повышаете его на 31, его знак меняется.Затем при понижении частоты знак дублируется, и в результате получается битовая комбинация 0xffffffff.

. Вы можете исправить это так:

int temp = (1UL << 31) >> 31;

GCC предупреждает об этомошибки, если у вас включен -Wall.

1 голос
/ 08 июля 2010

Когда вы делаете (1<<31), MSB, который является битом знака, устанавливается (становится 1). Затем, когда вы делаете правильный сдвиг, это знак расширяется. Следовательно, вы получите -1. Решение: (1UL << 31) >> 31.

1 голос
/ 08 июля 2010

int подписано.

что за "проблема" - что вы пытаетесь сделать?

int i = (1<<31); // i = -2147483648
i>>31;  // i = -1

unsigned int i = (1<<31); // i = 2147483648
i>>31;  // i = 1

ps ch - хороший интерпретатор командной строки 'c' для окон, который позволяет вам пробовать подобные вещи без компиляции, а также предоставляет командную оболочку unix. Смотри http://www.drdobbs.com/184402054

0 голосов
/ 08 июля 2010

бит для обозначения знака устанавливается, когда вы делаете « такой » сдвиг влево на целочисленную переменнуюОтсюда и результат.

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