Подтвердить что ты не робот

Как получить побитовые данные из целочисленного значения в C?

Я хочу извлечь биты десятичного числа.

Например, 7 является двоичным 0111, и я хочу получить 0 1 1 1 все биты, хранящиеся в bool. Как я могу это сделать?

ОК, цикл не является хорошим вариантом, могу ли я сделать что-то еще для этого?

4b9b3361

Ответ 1

Если вы хотите 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");
}

Ответ 2

В соответствии с просьбой я решил распространить свой комментарий на указательный палец на полноценный ответ. Хотя его ответ правильный, он излишне сложный. Кроме того, все текущие ответы используют подписанный 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 на месте и тем самым позволяет использовать постоянную ширину, однобитовый сдвиг, который может быть более эффективным для некоторых архитектур.

Ответ 3

Вот один из способов сделать это - есть много других:

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);

Ответ 4

Здесь очень простой способ сделать это;

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;
}

Ответ 5

Если вам не нужны какие-либо петли, вам придется написать:

#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;
}

Как показано здесь, это также работает в инициализаторе.

Ответ 6

@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;
}

Ответ 7

Используя std::bitset

int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();

Ответ 8

#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;
}