Странная ошибка - PullRequest
       2

Странная ошибка

2 голосов
/ 27 марта 2011

У меня есть простая функция:

int bitcount( unsigned );

int shiftbit( unsigned val ) {
    return (int)(~0U << (( sizeof(int)*CHAR_BIT ) - bitcount(val)));
}

Я подсчитываю количество бит в целом числе, а затем создаю битовую маску, в которой это число битов оставлено в порядке.Например, 0xABCD имеет 10 установленных битов и возвращает маску 0xFFC0000.

Функция отлично работает, за исключением случаев, когда значение счетчика битов равно нулю, в этом случае я получаю -1, 0xffffffff, когда мне просто нужно получить пустую битовую маску, т.е.0x0.Мне просто не понятно, почему это должно работать для каждого случая, кроме нуля.

Ответ

Так что я закончил тем, что изменил код следующим образом, который работает нормально и долженбыть портативным:

int shiftbit( unsigned val ) {
    int bCount = bitcount(val);
    return bCount ? (~0 << (( sizeof(int)*CHAR_BIT ) - bCount)) : 0;
}

Ответы [ 3 ]

9 голосов
/ 27 марта 2011

Результат операции сдвига не определен, если число сдвинутых битов больше, чем или равно числу битов в сдвинутом значении.Таким образом, сдвиг 32-битного значения на 32 не гарантирует ничего особенного.

4 голосов
/ 27 марта 2011

Потому что в C результат не определен, если вы сдвигаете операнд размером x бит на x бит. Так, например, 1 << 32 не определено (при условии sizeof(int) == 4)

0 голосов
/ 27 марта 2011

В C результат сдвига зависит от реализации. С процессорами x86 вы можете быть уверены, что операндом сдвига является модуль-32 (в 32-битном режиме). См. Стр. 3-623 этого документа:

FTP: //download.intel.com/design/intarch/manuals/24319101.pdf

"Операндом-адресатом может быть регистр или ячейка памяти. Операндом-счетчиком может быть немедленное значение или регистр CL. Счет замаскирован до пяти бит , что ограничивает диапазон счета от 0 до 31. Для счетчика 1 "

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