Чтение и изменение битов в 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;