Вращение Бит с подписанным полукоксом (С)?

голоса
2

Я пытаюсь повернуть подписанную символ ( *c), который в двоичном виде 10011010, правильные 4 ( numRotate) места. Желаемый результат после сдвига 10101001. Код , который я в настоящее время является:

void right(char *c, int numRotate) {
    *c = (*c >> numRotate) | (*c << (8 - numRotate));
}

Согласно тому , что я узнал, это , по- видимому , должны работать , чтобы сделать нужный мне сдвиг правильно. Вместо того, чтобы результат я получаю 11111001. Я не уверен , что это неправильно. Может ли это быть проблема с signedпротив unsigned charтипов данных? Все ресурсы , я рассматривающие использовать только неподписанные тип данных.

Задан 20/10/2018 в 05:26
источник пользователем
На других языках...                            


2 ответов

голоса
0

Сдвиг вправо отрицательное значение имеет реализации определяется поведение. Шаблон 10011010имеет отрицательное значение , если charэто 8-битные и знаковое , по умолчанию на вашей платформе. Вы должны использовать , unsigned charчтобы иметь определенное поведение для ваших целей:

void right(char *c, int numRotate) {
    *c = ((unsigned char)*c >> numRotate) | ((unsigned char)*c << (8 - numRotate));
}
Ответил 20/10/2018 в 07:00
источник пользователем

голоса
0

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

void right(unsigned char *c, int numRotate) {
    *c = (*c >> numRotate) | (*c << (8 - numRotate));
}

С подписанным целым правом оператора сдвиг дополнит остальные пространства с знаковым битом (MSB), так что:

10011010 >> 4 == 11111001
01011010 >> 4 == 00000101

Ответ от вопроса я связан утверждает это компилятор / платформу. Это так, чтобы сделать общую методику оптимизации по заменяющего умножения / деления на степени 2 с Bitshift операции работают с отрицательными числами. Пример:

#include <stdio.h>

int main()
{
    char x = -4;
    printf("0x%x -> %i\n", x, x);

    x <<= 1; //multiply by 2^1 = 2
    printf("0x%x -> %i\n", x, x);

    x >>= 2; //divide by 2^2 =4
    printf("0x%x -> %i\n", x, x);

    return 0;
}

Выход:

0xfffffffc -> -4
0xfffffff8 -> -8
0xfffffffe -> -2
Ответил 20/10/2018 в 06:07
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more