Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: booleans in C

  1. #1
    Join Date
    Apr 2009
    Location
    Germany
    Beans
    2,134
    Distro
    Ubuntu Development Release

    booleans in C

    hi,
    if have a huge array of char's to check some status. It should only save 0 or one.
    currently it looks something like that:
    Code:
    #define INDEX(a,b,c) (a*size2*size3 + b*size3 + c)
    ...
    char * ar = malloc(size1*size2*size3)
    ...
    ar[INDEX(i,j,k)] = 1
    ...
    if (ar[INDEX(i,j,k)])
    ...
    a char are 8 bit so I could theoretically save the same information in an eighth of the memory.
    I'm currently thinking of a bitfield but unfortunately you can't address members of a bitfield so I need to calculate the member from the index requiring a bit of runtime overhead.
    Is there a way to do this in C with less or even no overhead?

  2. #2
    Join Date
    Jun 2008
    Location
    California, USA
    Beans
    1,030
    Distro
    Ubuntu 9.04 Jaunty Jackalope

    Re: booleans in C

    How about looking into stdbool.h? That'll allow you to use the bool type directly.

    Blog | I'm available for programming contributions. C & Python.
    Intel Core i7 920 | EVGA x58 SLI | NVidia GeForce 8600 GT | WD 500GB HDD | Corsair XMS3 3GB | Ubuntu 9.04

  3. #3
    Join Date
    Apr 2009
    Location
    Germany
    Beans
    2,134
    Distro
    Ubuntu Development Release

    Re: booleans in C

    stdbool.h only seems to typedef an integer to a bool and define true and false
    so that would not really help me reduce memory usage

  4. #4
    Join Date
    Jan 2008
    Beans
    1,532

    Re: booleans in C

    You can do this in C, but you have to do it manually with bit manipulation (untested code):
    Code:
    typedef bitfield unsinged char;
    
    int is_set(bitfield field, int pos) {
        return (field & (1 << pos));
    }
    
    int set(bitfield* field, int pos) {
        *field |= (1 << pos);
    }
    
    int unset(bitfield* field, int pos) {
        *field &= ~(1 << pos);
    }
    You could change the char to an long in the typedef above to get (probably) 64 boolean values. For anything else, you'd have to use arrays which would add a bit of logic, but it still isn't too bad.

  5. #5
    Join Date
    Apr 2009
    Location
    Germany
    Beans
    2,134
    Distro
    Ubuntu Development Release

    Re: booleans in C

    perfect thanks

    this is my code for arrays in case someone is interested:
    Code:
    #define INDEX(a,b) (a*SIZE+b)
    
    int is_set(bitfield *field, int pos) {
    	div_t res = div(pos,8);
    	return (field[res.quot] & (1 << res.rem));
    }
    
    int set(bitfield* field, int pos) {
    	div_t res = div(pos,8);
    	field[res.quot] |= (1 << res.rem);
    }
    
    int unset(bitfield* field, int pos) {
    	div_t res = div(pos,8);
    	field[res.quot] &= ~(1 << res.rem);
    }
    ..
    set(bf,INDEX(2,3));

  6. #6
    Join Date
    Jul 2008
    Location
    Dublin, Ireland
    Beans
    633
    Distro
    Ubuntu 9.10 Karmic Koala

    Re: booleans in C

    I don't believe in early optimization, nor in macros, but if you really want to go for it...

    If you intend on using 8 bits (char) then you can use a macro/function to calculate the offset in a faster way by manipulating bits.

    Code:
    #define DIV_8( x ) ( (x) >> 3 )
    #define MOD_8( x ) ( (x) & 0x07 )
    Then you can avoid shifting to get the bit mask by precomputing the eight bit masks you will need:

    Code:
    char masks[] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
    So that the mask you want to apply is `mask[ MOD_8( POS(x, y) ) ]` in your code, for just one indirection.

    Code:
    // SET is easiest, can precompute the position and keep it, as it does not return it can be a
    // block of code, it is also the safest as arguments are only used once
    #define SET( data, x, y ) { register int pos=POS((x),(y)); (data)[ DIV_8(pos) ] |= mask[ MOD_8(pos) ]; } 
    
    #define GET( data, x, y) ((data)[ DIV_8( POS((x),(y)) ) ] & mask[ MOD_8( POS((x),(y)) ) ]
    Of course, the compiler can do anything it wants to with the register keyword, but in most cases (even if you did not actually requested it) it will be able to keep it in a register (the scope is minimal, just three instructions all of which do use the variable).

    Now, I recommend that you do not go this way and instead use regular functions. At any rate, and seeing the use of macros in your OP, note that you should use parenthesis around all the arguments to avoid problems with the code after the macro expansion. Also note that if an argument is used more than once inside the macro (as in GET) you risk users having unexpected results when they call the macro: GET( i++, j++ ) will increment both i and j variables twice (as compared to the SET( i++, j++ ) that will only increment each variable once.

    A last remark, how big is a HUGE array of bools? Note that you are sacrificing performance for memory, and current systems do have lots of memory (and CPU for that matter), but anyway, given current hardware, in most cases you would be better helping programmers (that is regular functions, regular data structures) than helping the computer. Just think of how much your time costs as compared to CPU/memory costs... how much work will you do to avoid buying a 4 Gb ram module for less than 75€, how much work do you want to spend to save for a 10% performance that can be payed by 50€ worth of CPU upgrade (from one frequency to the next would probably be less than that, just rough numbers).
    Last edited by dribeas; September 8th, 2009 at 12:34 AM.

  7. #7
    Join Date
    Jan 2007
    Location
    Utah
    Beans
    550

    Re: booleans in C

    It is much better to simply use bit operators than to create a fancy new datatype.

  8. #8
    Join Date
    Aug 2009
    Beans
    56
    Distro
    Ubuntu 9.10 Karmic Koala

    Re: booleans in C

    I would suggest creating a function that returns a string. it returns in the format of an 8 bit binary code. "00110101", for example. Essentially, it converts a char number into a binary string format, which you can then check, and theoretically store 8 true/false values within one byte of memory.
    int yourSkill = NULL;
    int n0OB = yourSkill;
    int you = n0OB;

  9. #9
    Join Date
    Aug 2005
    Location
    Fargo, ND, USA
    Beans
    1,499
    Distro
    Kubuntu 10.04 Lucid Lynx

    Re: booleans in C

    Quote Originally Posted by socool274 View Post
    I would suggest creating a function that returns a string. it returns in the format of an 8 bit binary code. "00110101", for example. Essentially, it converts a char number into a binary string format, which you can then check, and theoretically store 8 true/false values within one byte of memory.
    Yuck. How on earth is this better than what was described in first post?
    Help yourself: Search the community docs or try other resources.
    Quote Originally Posted by Henry Spencer
    Those who do not understand Unix are condemned to reinvent it, poorly.
    Let science use your computer when you aren't: Folding@Home.

  10. #10
    Join Date
    Jul 2008
    Beans
    1,491

    Re: booleans in C

    Quote Originally Posted by TheBuzzSaw View Post
    It is much better to simply use bit operators than to create a fancy new datatype.
    Quite, in mock-C:
    Code:
    /**
     * Extracts a bit as boolean value from a data array
     * index = 0 based index of the bit to look up (e.g. the first bit has index 0)
     * data = the data buffer that holds your bits, accessible as array
     * returns true if the bit is a 1 (on), false if it is a 0 (off). 
     */
    boolean extractBit(byte[] data, int index) {
      int charIndex = index >> 3;
      int bitIndex = index & 0x7; // the mod 8 operation
      return ( data[charIndex] & (1 << bitIndex) ) > 0;
    }
    Last edited by Reiger; September 8th, 2009 at 01:48 AM.

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •