Я хочу извлечь биты десятичного числа.
Например, 7 является двоичным 0111, и я хочу получить 0 1 1 1 все биты, хранящиеся в bool. Как я могу это сделать?
ОК, цикл не является хорошим вариантом, могу ли я сделать что-то еще для этого?
Я хочу извлечь биты десятичного числа.
Например, 7 является двоичным 0111, и я хочу получить 0 1 1 1 все биты, хранящиеся в bool. Как я могу это сделать?
ОК, цикл не является хорошим вариантом, могу ли я сделать что-то еще для этого?
Если вы хотите k-й бит n, тогда сделайте
(n & ( 1 << k )) >> k
Здесь мы создаем маску, применяем маску к n, а затем правое смещение маскированного значения, чтобы получить только тот бит, который мы хотим. Мы могли бы записать его более полно:
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
Подробнее о бит-масках здесь.
Вот программа:
#include <stdio.h>
#include <stdlib.h>
int *get_bits(int n, int bitswanted){
int *bits = malloc(sizeof(int) * bitswanted);
int k;
for(k=0; k<bitswanted; k++){
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
bits[k] = thebit;
}
return bits;
}
int main(){
int n=7;
int bitswanted = 5;
int *bits = get_bits(n, bitswanted);
printf("%d = ", n);
int i;
for(i=bitswanted-1; i>=0;i--){
printf("%d ", bits[i]);
}
printf("\n");
}
В соответствии с просьбой я решил распространить свой комментарий на указательный палец на полноценный ответ. Хотя его ответ правильный, он излишне сложный. Кроме того, все текущие ответы используют подписанный int
для представления значений. Это опасно, так как смещение отрицательных значений в соответствии с реализацией (т.е. Не переносимое) и смещение влево может привести к поведению undefined (см. этот вопрос).
Путем правого смещения нужного бита в наименее значимое положение бит, маскирование может выполняться с помощью 1
. Нет необходимости вычислять новое значение маски для каждого бита.
(n >> k) & 1
Как полная программа, вычисление (и последующая печать) массива одноразрядных значений:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
unsigned
input = 0b0111u,
n_bits = 4u,
*bits = (unsigned*)malloc(sizeof(unsigned) * n_bits),
bit = 0;
for(bit = 0; bit < n_bits; ++bit)
bits[bit] = (input >> bit) & 1;
for(bit = n_bits; bit--;)
printf("%u", bits[bit]);
printf("\n");
free(bits);
}
Предполагая, что вы хотите рассчитать все биты, как в этом случае, а не конкретный, цикл можно дополнительно изменить на
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
Это изменяет input
на месте и тем самым позволяет использовать постоянную ширину, однобитовый сдвиг, который может быть более эффективным для некоторых архитектур.
Вот один из способов сделать это - есть много других:
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
Трудно понять, почему использование цикла нежелательно, но достаточно просто развернуть цикл:
bool b[4];
int v = 7; // number to dissect
b [0] = 0 != (v & (1 << 0));
b [1] = 0 != (v & (1 << 1));
b [2] = 0 != (v & (1 << 2));
b [3] = 0 != (v & (1 << 3));
Или вычисляя константные выражения в последних четырех утверждениях:
b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);
Здесь очень простой способ сделать это;
int main()
{
int s=7,l=1;
vector <bool> v;
v.clear();
while (l <= 4)
{
v.push_back(s%2);
s /= 2;
l++;
}
for (l=(v.size()-1); l >= 0; l--)
{
cout<<v[l]<<" ";
}
return 0;
}
Если вам не нужны какие-либо петли, вам придется написать:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num = 7;
#if 0
bool arr[4] = { (num&1) ?true: false, (num&2) ?true: false, (num&4) ?true: false, (num&8) ?true: false };
#else
#define BTB(v,i) ((v) & (1u << (i))) ? true : false
bool arr[4] = { BTB(num,0), BTB(num,1), BTB(num,2), BTB(num,3)};
#undef BTB
#endif
printf("%d %d %d %d\n", arr[3], arr[2], arr[1], arr[0]);
return 0;
}
Как показано здесь, это также работает в инициализаторе.
@prateek благодарим вас за помощь. Я переписал функцию с комментариями для использования в программе. Увеличьте 8 для большего количества бит (до 32 для целого числа).
std::vector <bool> bits_from_int (int integer) // discern which bits of PLC codes are true
{
std::vector <bool> bool_bits;
// continously divide the integer by 2, if there is no remainder, the bit is 1, else it 0
for (int i = 0; i < 8; i++)
{
bool_bits.push_back (integer%2); // remainder of dividing by 2
integer /= 2; // integer equals itself divided by 2
}
return bool_bits;
}
Используя std::bitset
int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();
#include <stdio.h>
int main(void)
{
int number = 7; /* signed */
int vbool[8 * sizeof(int)];
int i;
for (i = 0; i < 8 * sizeof(int); i++)
{
vbool[i] = number<<i < 0;
printf("%d", vbool[i]);
}
return 0;
}