How do I get bit-by-bit data from an integer value in C?

后端 未结 8 1101
时光说笑
时光说笑 2020-11-30 17:36

I want to extract bits of a decimal number.

For example, 7 is binary 0111, and I want to get 0 1 1 1 all bits stored in bool. How can I do so?

OK, a loop is

相关标签:
8条回答
  • 2020-11-30 17:38

    Here's a very simple way to do it;

    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;
    }
    
    0 讨论(0)
  • 2020-11-30 17:38

    If you don't want any loops, you'll have to write it out:

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

    As demonstrated here, this also works in an initializer.

    0 讨论(0)
  • 2020-11-30 17:38
    #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;
    }
    
    0 讨论(0)
  • 2020-11-30 17:40

    @prateek thank you for your help. I rewrote the function with comments for use in a program. Increase 8 for more bits (up to 32 for an integer).

    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;
    }
    
    0 讨论(0)
  • 2020-11-30 17:46

    Here's one way to do it—there are many others:

    bool b[4];
    int v = 7;  // number to dissect
    
    for (int j = 0;  j < 4;  ++j)
       b [j] =  0 != (v & (1 << j));
    

    It is hard to understand why use of a loop is not desired, but it is easy enough to unroll the loop:

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

    Or evaluating constant expressions in the last four statements:

    b [0] =  0 != (v & 1);
    b [1] =  0 != (v & 2);
    b [2] =  0 != (v & 4);
    b [3] =  0 != (v & 8);
    
    0 讨论(0)
  • 2020-11-30 17:52

    As requested, I decided to extend my comment on forefinger's answer to a full-fledged answer. Although his answer is correct, it is needlessly complex. Furthermore all current answers use signed ints to represent the values. This is dangerous, as right-shifting of negative values is implementation-defined (i.e. not portable) and left-shifting can lead to undefined behavior (see this question).

    By right-shifting the desired bit into the least significant bit position, masking can be done with 1. No need to compute a new mask value for each bit.

    (n >> k) & 1
    

    As a complete program, computing (and subsequently printing) an array of single bit values:

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

    Assuming that you want to calculate all bits as in this case, and not a specific one, the loop can be further changed to

    for(bit = 0; bit < n_bits; ++bit, input >>= 1)
        bits[bit] = input & 1;
    

    This modifies input in place and thereby allows the use of a constant width, single-bit shift, which may be more efficient on some architectures.

    0 讨论(0)
提交回复
热议问题