Thread: Bitmanipulation in C

  1. #1
    Registered User
    Join Date
    Jan 2015
    Posts
    8

    Question Bitmanipulation in C

    The task is to return the number of bits set to true.

    Here is my code:
    Code:
    int cardinalityBS(PBitSet _this) {
        int s, counter = 0;
    
    
        for(s = 0; s < 31; s++) {
            counter += _this->bits & 1;
            _this->bits <<= 1;
        }
    
    
        return counter;
    }
    The code is not working, since whenever I set _this->bits to a number, it returns me the wrong result. My question is: How could I fix this problem because the code looks perfect for me.

  2. #2
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Shouldn't it be
    Code:
    coutner += _this->bits & (1 << s);

  3. #3
    Registered User
    Join Date
    Jan 2015
    Posts
    8
    Thank you very much for your answer, can I ask just one more question?

    Code:
    void clearBS(PBitSet _this, int fromIndex, int toIndex) {
         int c;
    
    
         for(c = fromIndex; c < toIndex; c++) {
            _this->bits &= (0 << c);
         }
    }
    The goal is here to set the bits of an integer from "fromIndex" to "toIndex" to false but the code above does not work. (Whenever I print the integer number to test my code, if my fromIndex and toIndex are bigger than 0, my number will be 0 either.) What did I do wrong?

  4. #4
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Hmm... Look at this.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    void clear_bits(const int       begin,
                    const int       end,
                          unsigned *x)
    {
        if (begin < 0 || end < 0 || begin > 32 || end > 32)
            return;
    
    
        unsigned cpy = *x;
    
    
        for (int i = begin; i < end; ++i)
        {
            cpy &= ~(1 << i);
        }
    
    
        *x = cpy;
    }
    
    
    int main(void)
    {
        // all bits are set because I couldn't
        // get UINT_MAX to work
        unsigned x = 0xffffffff;
    
    
        clear_bits(22, 32, &x);
    
    
        printf("%u\n", x);
    }
    You're problem was that you need to be using
    Code:
    i &= ~(1 << bit)

  5. #5
    Registered User
    Join Date
    Jan 2015
    Posts
    8
    Thanks you, it's working now. But why is i &= ~(1 << bit) actually not the same as i &= (0 << bit) ??

  6. #6
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    void clearBS(PBitSet _this, int fromIndex, int toIndex)
    O_o

    You don't need a loop.

    The C and C++ languages require `unsigned' integers to have specific characteristics.

    The number of bits to be cleared: `toIndex - fromIndex'
    The offset of the first bit to be clear: `fromIndex'

    You can easily create a string of bits using that information which may be used as a mask which can be complemented allowing you to set or clear the range with a single operation.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  8. #8
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Hmm... phantom, is this what you had in mind? Or do you have a better implementation?
    Code:
    void set_bits(const int       begin,
                  const int       end,
                        unsigned *x)
    {
        const int n = end - begin;
    
    
        unsigned val = (1 << n) - 1;
        val <<= begin;
    
    
        unsigned tmp = *x;
    
    
        tmp |= val;
    
    
        *x = tmp;
    }
    
    
    int main(void)
    {
        unsigned x = 0;
    
    
        set_bits(1, 5, &x);    
    
    
        printf("%u\n", x);
    
    
        return 0;
    }

Popular pages Recent additions subscribe to a feed

Tags for this Thread