Чтение и изменение битов в C uint32_t

Я использую этот код

int get_bit(int n, int bitnr) {
int mask = 1 << bitnr;
int masked_n = n & mask;
int thebit = masked_n >> bitnr;
return thebit;
}

void printbits(uint32_t bits) {
    int i;
    for (i = 0; i < 32; i++)
        printf("%d", get_bit(bits, i));
    printf("\n");
}

получить и распечатать биты uint32_t, а в другой функции этот код

uint32_t bits= 0;
bits|= 1<< 0;

изменить самый старший бит (самый левый) с 0 на 1.

проблема заключается в том, что при печати битов с использованием функции printbits он печатает их правильно, но при использовании printf("%#x", bits); Я получаю шестнадцатеричное значение битов, как будто они читаются справа налево!

поэтому printbits дает мне "10000000000000000000000000000000", но напечатанное шестнадцатеричное значение равно "00000000000000000000000000000001".

Помощь оценена

4 ответа

Решение

Изменение наиболее значимого бита:

Эта строка:

bits |= 1<< 0;

изменяет младший значащий бит (LSB). 1 << 0 равняется 1что не очень существенно:).

Но если вы делаете:

bits |= 1 << 31;

или же

bits |= 0x80000000;

Вы бы на самом деле изменили самый старший бит (MSB).

Печать числа в двоичном виде:

Ваш код на самом деле печатает число справа налево. Вы должны изменить свой цикл на декремент.

for (i = 31; i >= 0; i--)

И если печать неправильным способом подходит вам (кто знает...), попробуйте это:

uint32_t n = 41;
while (n) {
    printf("%d", n & 1);
    n >>= 1;
}

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

void printbits(uint32_t n) {
    if (n) {
        printbits(n >> 1);
        printf("%d", n & 1);
    }
}

Этот алгоритм работает для любой базы с небольшими изменениями.

Этот код bits|= 1<< 0; устанавливает младший, не самый значимый бит в целом числе. То же самое относится и к вашему get_bit функция - она ​​нумерует биты справа налево.

(1 << 0) наименее значимый бит. (1 << 31) будет самым значительным битом.

Ваша функция печати печатает биты в порядке возрастания (неправильный путь). Вы должны полностью изменить for цикл:

for (i = 31; i >= 0; i--)

Это меняет первую цифру справа (наименее важный бит):

 uint32_t bits= 0;
 bits|= 1<< 0;

Используйте что-то вроде:

uint32_t bits= 0;
bits |= 0x8000;
Другие вопросы по тегам