Thread: Bit Sized Variable

  1. #1
    Registered User
    Join Date
    Feb 2011
    Posts
    29

    Bit Sized Variable

    ***Background Information

    A byte is 8 bits.

    Bool is 1 byte.
    Char is 1 byte.
    Int is 4 bytes (therefore: 32 bits)

    ***What I want..

    I've been programming for quite a while.
    As many know, less bytes = better performance.
    Many replace 'int' with 'char' when doing small tasks. Like, how many hours are in a day. You don't need the range of 0 - ~32000 (int), 0-255 (char) is sufficient.

    However, I want to have true BOOLEAN, instead of 0-255 possible bool.

    ***How would I do this?

    In C, or any language (if there is one)..
    I'd like to create a bit-sized variable.

    Example (in text):
    declare new type of 3 bits named 3bit
    Then this new 3 bit variable would have
    000 - 111
    In base 10: 0 - 7

    Then when I declare the 3 bit variable, instead of the 8 bit variable, I theoretically save 5 bits during creation, but have less bits to actually manipulate.

    If there is a way, it would then be possible to create a 1 bit variable, which would be (bool), so when you do a bit-test (or a simple if statement), it will only have 1 bit to check and there would be no waste to the other 7. But I'm not looking for a response to save the speed for bool solely. I'd like the power to create a 3, 4.. 17, 11, any size bit variable. Instead of crunching 8 bits together, which is just a structure of chars combined.

    Thank you, I'd love to hear this is possible. Cannot find a narrow result in searches.

    Crosility

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    >> As many know, less bytes = better performance.
    Is it?
    Boolean Expressions and Variables
    The C Book — Bitfields

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    As many know, less bytes = better performance.
    That's not necessarily true.
    In C, or any language (if there is one)..
    I'd like to create a bit-sized variable.
    You can't in C. You can use a bitfield:
    Code:
    struct b
    {
      unsigned char b:1;
    };
    The “b” member is a bitfield of size 1, but your struct will still be at least a byte long (no type in C can be smaller than a byte). The advantage to bitfields is that you can pack many elements into a byte, not that you can create a type smaller than a byte.

    If you're worried about performance, use a profiler like gprof or callgrind. Don't make assumptions about what will be fast, make tests.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Crosility View Post
    Many replace 'int' with 'char' when doing small tasks. Like, how many hours are in a day. You don't need the range of 0 - ~32000 (int), 0-255 (char) is sufficient.
    If you're refering to a variable used as a loop counter, then those "many" are in fact a small number of programmers who are fools who do not know that using a smaller data type in such a circumstance only hurts performance.
    The only time to use a smaller data type is when you have a huge number of them, because it is only then that the corresponding saving or memory has a beneficial impact.

    PCs are not bit-addressable so what you want simply isn't possible, and if it were it would only hurt performance. You can emulate a 1-bit data type if you pack several of them into bitfields, but this is limiting in that you can't take the address of the individual fields, and it is slower than just using an int if you only have a small number of them.

    BTW, the range of an int is typically -2147483648 to 2147483647.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    Registered User
    Join Date
    Feb 2011
    Posts
    29
    That's not necessarily true.
    Can you explain why this isn't true?
    Wouldn't the CPU only be checking / storing 1 bit of information. Instead of going through a check of 8 bits of information, or storing 7 unnecessary bits?
    I would believe that if you stored a smaller variable for the CPU to process it would be easier to access, and also easier to change.

    You can't in C. You can use a bitfield:
    Code:
    struct b
    {
      unsigned char b:1;
    };
    The “b” member is a bitfield of size 1, but your struct will still be at least a byte long (no type in C can be smaller than a byte). The advantage to bitfields is that you can pack many elements into a byte, not that you can create a type smaller than a byte.

    If you're worried about performance, use a profiler like gprof or callgrind. Don't make assumptions about what will be fast, make tests.
    I actually have never looked into bit fields till Salem posted the link. From reading the wikipedia version a few times, it doesn't look as if your actually getting 1 bit, but an entire char (8 bits) of information.

    The reason I assume the speed of using bit variables, because of the obvious - it holds less. I am still not sure how I am suppose to test if it is quicker or not, because I can't do the test of passing a single bit of information, compared to a single byte.

    Now, I have possibly a silly question.

    Code:
    struct bb {
    unsigned char a : 1;
    unsigned char b : 1;
    unsigned char c : 1;
    unsigned char d : 1;
    ... // etc.
    } b;
    Does this create a 1 byte variable, in which I can edit b by doing
    b.a = 1;
    ?

    Or would this create a 4 byte structure because I have declared 4 unsigned chars?

    I did some reading, some clarity would be nice.

    If I create this, and say add
    unsigned char remainder : 4;
    to the end of the structure

    I would then have a full byte? Then each variable in the structure is accessible.. therefore saving memory. So, if I had 4 true false statements, and 1 4bit number I needed to store.. I could?
    Last edited by Crosility; 02-22-2011 at 10:18 AM.

  7. #7
    Registered User
    Join Date
    Feb 2011
    Posts
    29
    Quote Originally Posted by iMalc View Post
    If you're refering to a variable used as a loop counter, then those "many"
    ... //scroll up to read//
    BTW, the range of an int is typically -2147483648 to 2147483647.
    Haha, guess my compiler is slightly outdated, and my reading is not the same as the posted. I have 2 byte ints. (Reran a quick loop to check.)
    Haha. Anyhow..

    I understand now that the processor can't access 1 bit data types. But I still don't understand how it'd hurt performance, because it'd be the same number of variables accessed. If you made 50 variables of char/int/long int in one program. Why wouldn't a program where you allocate 50 variables of a self-bit width variable be any different? Except to save space and increase speed?

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by Crosility View Post
    Can you explain why this isn't true?
    Wouldn't the CPU only be checking / storing 1 bit of information. Instead of going through a check of 8 bits of information, or storing 7 unnecessary bits?
    I would believe that if you stored a smaller variable for the CPU to process it would be easier to access, and also easier to change.
    Altho' it seems like using less memory would speedup things, yet it takes more micro processing for bitfileds due to reasons like specialized instructions needed to unpack them.
    Quote Originally Posted by Crosility View Post
    I actually have never looked into bit fields till Salem posted the link. From reading the wikipedia version a few times, it doesn't look as if your actually getting 1 bit, but an entire char (8 bits) of information.

    The reason I assume the speed of using bit variables, because of the obvious - it holds more. I am still not sure how I am suppose to test if it is quicker or not, because I can't do the test of passing a single bit of information, compared to a single byte.
    Yep! you can.
    Quote Originally Posted by Crosility View Post
    Now, I have possibly a silly question.

    Code:
    struct b {
    unsigned char a : 1;
    unsigned char b : 1;
    unsigned char c : 1;
    unsigned char d : 1;
    ... // etc.
    };
    Does this create a 1 byte variable, in which I can edit b by doing
    b.a = 1;
    ?

    Or would this create a 4 byte structure because I have declared 4 unsigned chars?
    It'd create a struct variable that is 1 byte long because bitfields are packed together for compactness.
    Quote Originally Posted by Crosility View Post
    I did some reading, some clarity would be nice.


    If I create this, and say add
    unsigned char remainder : 4;
    to the end of the structure

    I would then have a full byte? Then each variable in the structure is accessible.. therefore saving memory. So, if I had 4 true false statements, and 1 4bit number I needed to store.. I could?
    Savings in memory doesn't equate to better performance because of the specialized processing needed for bitfields.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Accessing bit fields is often worse performance than accessing bytes (or words), especially when doing a write. To write one bit, you have to read the whole byte/word, modify the bit in question and then write out the whole thing again.

    Even reading can be more expensive, if your machine cannot incorporate a shift operation at the same time as reading the storage word (many can't).

    Writing whole bytes/words is just that - a single write.

    Unless you have some pretty unique circumstances (like needing to store millions of bools, or very limited memory), just use the bool type.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Feb 2011
    Posts
    29
    So, from what each one of you is saying is:

    When computers were made, and then the processes that access information, someone made it so only an entire byte is read/writeable. Unless you used bit operations, but because the information is stored in a byte, it would need to deconstruct the byte, change the information, then put the byte back together.

    That is sad. I wish they'd made the processes access 2 bits, or even 1 bit, not 8!

    Would I be taking a performance hit if I had 8 bools stored as a single byte?
    Because of the (de / re)construction of the byte (due to bit shifting), using a larger amount of space would actually be faster?

    I wish there was a way around this. Think of the possibilities, if the processes(processor) could read/write single bits, and spit them back out. You could actually manipulate data much faster.

    Now I understand bitfield, and may do a test to see the time in seconds it takes to edit the information 500 times, for both ways (bool, and if I did a 1 bit bool inside of a struct)

  11. #11
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Another option would be to use a single int to store several bits together. It would use less memory than a variable for each bool, but again, there's a performance hit since you have to do extra (bit-)operations to read/write them.
    If you understand what you're doing, you're not learning anything.

  12. #12
    Registered User
    Join Date
    Feb 2011
    Posts
    29
    Okay. I'm going to cut to the chase of why I'm asking.

    I am creating a game. (No, not in DOS, but it'll will comprise of a LOT of C code).

    The client would connect to a server. The server would pass information to the client. (And client to server).

    Well, say I have 8 images for different rotations. Having a 3 bit variable is perfect.
    A switch (case) statement to see what the 3 bit variable is, would allow it to display the image based on the number 0-7 (of a 3 bit variable).

    Now. I see the performance issue. However, when making a game (that obviously is going to interact over the internet). Would making bitfields be wise? Because If I pass 8 bools.. I'm using up (very quickly) 8 bytes of information on the internet usage.
    However, turning those 8 bools, into 1 bits, creating a 1 byte structure, passing the same information.. should use up less memory when being passed. Then, say.. the client could set 8 variables to the information stored in the bitfield, and use them?

    I know. It seems like a big waste of time. But my current struggle.. is creating a way to minimize internet usage, by using the least amount of memory possible. It may be more stressful for the processor, but as they upgrade, I suppose it can be ignored. Though more information can be passed, if I'm sending less amounts at a time, correct?
    Last edited by Crosility; 02-22-2011 at 10:53 AM.

  13. #13
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Graphical applications you'd know are a heck of a lot more resource intensive, and the fact that they use bitfields may have something to do with it

  14. #14
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Well, say I have 8 images for different rotations. Having a 3 bit variable is perfect.
    A case statement to see what the 3 bit variable is, would allow it to display the image based on the number 0-7 (of a 3 bit variable).
    You're not going to be passing a bit at a time over the network, so there's no point in trying to reduce all operations like that. You'll be passing at least a byte (and probably more).

    So you need a 3-bit variable? Even if you had one, you'd have to pass it as a byte, so just use (at least) a byte.

    You need 8 boolean values? Pack them all into a char and pass that, if you're really worried about network usage. Something like:
    Code:
    #define FLAG1 0x01
    #define FLAG2 0x02
    #define FLAG3 0x04
    /* ... */
    unsigned char flags = 0;
    if(set_flag_1) flags |= FLAG1;
    /* ... */
    if(flags & FLAG1) /* it is set */
    But really, it's a better idea to test to find where a bottleneck is rather than assume you know.

  15. #15
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Packing the bits into the smallest size data structure to be sent over a network is probably the way to go. I can't imagine the processing performance hit would even come close to outweighing the network gain. Of course, you're not going to be able to send only 3 bits at a time over the network. But if you can pack more than one value together then you'll be okay.
    If you understand what you're doing, you're not learning anything.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. spliting 16bit variable into LSB and MSB 8 bit variables
    By Spiral Prophet in forum C Programming
    Replies: 2
    Last Post: 10-30-2008, 02:28 PM
  2. Question about printing a variable???
    By Hoser83 in forum C++ Programming
    Replies: 2
    Last Post: 03-31-2006, 01:57 PM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. Replies: 7
    Last Post: 12-10-2004, 08:18 AM
  5. bit patterns of negtive numbers?
    By chunlee in forum C Programming
    Replies: 4
    Last Post: 11-08-2004, 08:20 AM

Tags for this Thread