Відповіді:
Якщо ви хочете 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");
}
structможе бути корисним перенесення даних на a , оскільки ви отримуєте всі необхідні дані за одну операцію.
На прохання я вирішив поширити свій коментар щодо відповіді вказівного пальця на повноцінну відповідь. Хоча його відповідь правильна, вона непотрібна. Крім того, всі поточні відповіді використовують підписані ints для представлення значень. Це небезпечно, оскільки зсув правого зміщення негативних значень визначено реалізацією (тобто не є переносним), а зміщення ліворуч може призвести до невизначеної поведінки (див. Це питання ).
Перемістивши потрібний біт у найменш значуще бітове положення, маскування можна зробити за допомогою 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);
@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's 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;
}
Якщо вам не потрібні петлі, вам доведеться виписати їх:
#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;
}
Як показано тут, це також працює в ініціалізаторі.
Використання std::bitset
int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();
(n >> k) & 1однаково справедливий і не вимагає обчислення маски, оскільки маска є постійною через зміщення перед маскуванням, а не навпаки.