Having trouble understanding these bitwise macros

Discussion in 'C Programming' started by Krumble Bunk, Oct 12, 2005.

  1. Krumble Bunk

    Krumble Bunk Guest

    Hello!

    First things first (but not necessarily in that order), this is a
    really great group, and has helped me understand more and more C
    everytime I read the postings, so thanks for a great learning
    environment!

    I am having difficulty understanding this bitwise macro (i've recently
    moved into working on these, using OpenSolaris source code -
    magnificent learning resource btw!)

    #define setbit(a, i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
    #define clrbit(a, i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
    #define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))

    where NBBY is defined as 8

    I imagine that "a" is a 32bit int, and i is the position of the bit in
    the word/int that wants to be set. I don't understand why they divide
    by NBBY though? I sort of understand the rest, but if someone could
    perhaps spare the time to explain the "setbit" macro, i can extrapolate
    the rest for myself.

    Many thanks!!

    KB
    Krumble Bunk, Oct 12, 2005
    #1
    1. Advertising

  2. Krumble Bunk

    Skarmander Guest

    Krumble Bunk wrote:
    > Hello!
    >
    > First things first (but not necessarily in that order), this is a
    > really great group, and has helped me understand more and more C
    > everytime I read the postings, so thanks for a great learning
    > environment!
    >
    > I am having difficulty understanding this bitwise macro (i've recently
    > moved into working on these, using OpenSolaris source code -
    > magnificent learning resource btw!)
    >
    > #define setbit(a, i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
    > #define clrbit(a, i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
    > #define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
    >
    > where NBBY is defined as 8
    >
    > I imagine that "a" is a 32bit int, and i is the position of the bit in
    > the word/int that wants to be set. I don't understand why they divide
    > by NBBY though? I sort of understand the rest, but if someone could
    > perhaps spare the time to explain the "setbit" macro, i can extrapolate
    > the rest for myself.
    >

    No, 'a' is not an int. It can't be, because the indexing operator []
    couldn't be applied.

    These macros are intended to maintain a bit array, where it is assumed
    that there are at least NBBY (Number of Bits per BYte, I assume) bits to
    every element of a (that is, 'a' will probably be of type 'unsigned
    char[]', for some size).

    They say a picture's worth a thousand words. Imagine 'a' like this

    a[0] a[1] a[2]
    01234567 01234567 01234567
    01010011 01000101 01011000 ...

    Here setbit(a, 14) expands to ((a)[14/8] |= (1 << (14%8)), hence a[1] |=
    1 << 6, setting bit 6 of a[1], which is the 15th bit in the collection.

    S.
    Skarmander, Oct 12, 2005
    #2
    1. Advertising

  3. Krumble Bunk

    pemo Guest

    "Krumble Bunk" <> wrote in message
    news:...
    > Hello!
    >
    > First things first (but not necessarily in that order), this is a
    > really great group, and has helped me understand more and more C
    > everytime I read the postings, so thanks for a great learning
    > environment!
    >
    > I am having difficulty understanding this bitwise macro (i've recently
    > moved into working on these, using OpenSolaris source code -
    > magnificent learning resource btw!)
    >
    > #define setbit(a, i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
    > #define clrbit(a, i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
    > #define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
    >
    > where NBBY is defined as 8
    >
    > I imagine that "a" is a 32bit int, and i is the position of the bit in
    > the word/int that wants to be set. I don't understand why they divide
    > by NBBY though? I sort of understand the rest, but if someone could
    > perhaps spare the time to explain the "setbit" macro, i can extrapolate
    > the rest for myself.
    >


    Seems to set/test a variable's bits through a pointer ...

    #include <stdio.h>

    #define NBBY 8

    #define setbit(a, i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
    #define clrbit(a, i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
    #define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))

    int main(void)
    {
    int b = 0;

    int * a = &b;

    puts("Before setbit");

    printf("a's address = %p b's value = %d\n", a, b);

    setbit(a, 2);

    puts("After setbit");

    printf("a's address = %p b's value = %d isset = %d\n", a, b,
    !!isset(a, 2));

    return 0;
    }

    Before setbit
    a's address = 0012FF78 b's value = 0
    After setbit
    a's address = 0012FF78 b's value = 4 isset = 1

    Code above translates to ...

    int main(void)
    {
    int b = 0;

    int * a = &b;

    puts("Before setbit");

    printf("a's address = %p b's value = %d\n", a, b);

    ((a)[(2)/8] |= 1<<((2)%8));

    puts("After setbit");

    printf("a's address = %p b's value = %d isset = %d\n", a, b,
    !!((a)[(2)/8] & (1<<((2)%8))));

    return 0;
    }
    pemo, Oct 12, 2005
    #3
  4. Krumble Bunk

    Krumble Bunk Guest

    pemo wrote:
    > "Krumble Bunk" <> wrote in message
    > news:...
    > > Hello!
    > >
    > > First things first (but not necessarily in that order), this is a
    > > really great group, and has helped me understand more and more C
    > > everytime I read the postings, so thanks for a great learning
    > > environment!
    > >
    > > I am having difficulty understanding this bitwise macro (i've recently
    > > moved into working on these, using OpenSolaris source code -
    > > magnificent learning resource btw!)
    > >
    > > #define setbit(a, i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
    > > #define clrbit(a, i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
    > > #define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
    > >
    > > where NBBY is defined as 8
    > >
    > > I imagine that "a" is a 32bit int, and i is the position of the bit in
    > > the word/int that wants to be set. I don't understand why they divide
    > > by NBBY though? I sort of understand the rest, but if someone could
    > > perhaps spare the time to explain the "setbit" macro, i can extrapolate
    > > the rest for myself.
    > >

    >
    > Seems to set/test a variable's bits through a pointer ...
    >
    > #include <stdio.h>
    >
    > #define NBBY 8
    >
    > #define setbit(a, i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
    > #define clrbit(a, i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
    > #define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
    >
    > int main(void)
    > {
    > int b = 0;
    >
    > int * a = &b;
    >
    > puts("Before setbit");
    >
    > printf("a's address = %p b's value = %d\n", a, b);
    >
    > setbit(a, 2);
    >
    > puts("After setbit");
    >
    > printf("a's address = %p b's value = %d isset = %d\n", a, b,
    > !!isset(a, 2));
    >
    > return 0;
    > }
    >
    > Before setbit
    > a's address = 0012FF78 b's value = 0
    > After setbit
    > a's address = 0012FF78 b's value = 4 isset = 1
    >
    > Code above translates to ...
    >
    > int main(void)
    > {
    > int b = 0;
    >
    > int * a = &b;
    >
    > puts("Before setbit");
    >
    > printf("a's address = %p b's value = %d\n", a, b);
    >
    > ((a)[(2)/8] |= 1<<((2)%8));
    >
    > puts("After setbit");
    >
    > printf("a's address = %p b's value = %d isset = %d\n", a, b,
    > !!((a)[(2)/8] & (1<<((2)%8))));
    >
    > return 0;
    > }


    Thanks to both of you for your superb replies - exactly what I was
    after!

    Thanks again -- kb
    Krumble Bunk, Oct 12, 2005
    #4
  5. Krumble Bunk

    Old Wolf Guest

    pemo wrote:
    > #include <stdio.h>
    >
    > #define NBBY 8


    There is a standard macro CHAR_BIT which tells the number of
    bits per byte.

    >
    > #define setbit(a, i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
    > #define clrbit(a, i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
    > #define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
    >
    > int main(void)
    > {
    > int b = 0;
    > int * a = &b;


    Should be: unsigned char *a = (unsigned char *)&b;

    Your example code would have failed if you use any index
    greater than 7.
    Old Wolf, Oct 12, 2005
    #5
  6. Krumble Bunk

    Skarmander Guest

    Old Wolf wrote:
    > pemo wrote:
    >
    >>#include <stdio.h>
    >>
    >>#define NBBY 8

    >
    >
    > There is a standard macro CHAR_BIT which tells the number of
    > bits per byte.
    >

    Depending on the problem at hand, it may or may not be correct to use
    CHAR_BIT rather than 8. For a generic bit array where the goal is to
    squeeze as many bits as possible in those bytes, CHAR_BIT is
    appropriate, but there may be a need for bit arrays that always use
    exactly 8 bits per char, even if it can store more.

    >>#define setbit(a, i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
    >>#define clrbit(a, i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
    >>#define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
    >>
    >>int main(void)
    >>{
    >> int b = 0;
    >> int * a = &b;

    >
    >
    > Should be: unsigned char *a = (unsigned char *)&b;
    >

    Not a good idea. Declaring b as an unsigned char[] of an appropriate
    size in the first place would be better. The code as originally posted
    isn't wrong, though.

    > Your example code would have failed if you use any index
    > greater than 7.
    >

    Obviously, and your revised version could fail for any index greater
    than 15. That's assuming that writing to parts of an int through an
    unsigned char* is defined in the first place, of course, which I don't know.

    S.
    Skarmander, Oct 12, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    80
    Views:
    2,418
    Stephen J. Bevan
    Nov 7, 2003
  2. Pyenos
    Replies:
    9
    Views:
    290
    WaterWalk
    Dec 29, 2006
  3. Replies:
    7
    Views:
    303
    Triple-DES
    Mar 14, 2008
  4. Jake Barnes
    Replies:
    3
    Views:
    110
    Thomas 'PointedEars' Lahn
    May 24, 2006
  5. Andrew Falanga
    Replies:
    2
    Views:
    201
    Andrew Falanga
    Nov 22, 2008
Loading...

Share This Page