tzippy
tzippy

Reputation: 6648

Creating an integer from three bool values as bits in C++

I have three bool values that represent bits. I want to have an integer in the form

true true true = 7
false true false = 2

I have

int val = 4*boolVal1 + 2*boolVal2 + boolVal3;

Is there another way, maybe even simpler?

Upvotes: 12

Views: 1145

Answers (4)

hroptatyr
hroptatyr

Reputation: 4829

If you know the endianness you could also use implementation-defined behaviour and bitsets, little-endian version:

union foo {
        unsigned int the_int;
        struct {
                unsigned int bit3:1
                unsigned int bit2:1
                unsigned int bit1:1
        };
};

and then to set them:

foo.bit1 = true;
foo.bit2 = false;
foo.bit3 = true;

and to read:

foo.the_int;

The big-endian version has the bits reversed and a lot of padding (29 bits if unsigned int is 32bits wide) in front.

Upvotes: 2

Tony Delroy
Tony Delroy

Reputation: 106244

Other than the multiplication and bitshifting, you could also use an enum to document the relationship. Not normally worth the effort, but just for completeness...

enum Encoding
{ 
    Flag3 = 1,      NotFlag3 = 0,
    Flag2 = 1 << 1, NotFlag2 = 0,
    Flag1 = 1 << 2, NotFlag1 = 0
};

int val = (boolVal1 ? Flag1 : NotFlag1) |
          (boolVal2 ? Flag2 : NotFlag2) |
          (boolVal3 ? Flag3 : NotFlag3);

Why on earth would you bother with this? It's just a bit more general, so you can potentially vary the Encoding values later without having to touch the potentially distributed code using actual values (for example, if you realised you'd left out a bit compared to the format of some file or network data you needed to parse, you can add it in just one place and recompile). Of course it's better just to provide a single encode / decode function anyway, and if you're adding new flags you'll still need it.

While having Flag1 and NotFlag1 may seem pointless, it's often the case that you have something like mutually exclusive values like say Sticky and Floating, or Male and Female, and there's no particular reason to force clients to check for say Floating as !Sticky or Female as !Male etc..

Upvotes: 4

Ivan Vergiliev
Ivan Vergiliev

Reputation: 3841

Or you can use Horner's method:

int val = (((boolVal1 << 1) | boolVal2) << 1) | boolVal3.

This also makes it easier to add or remove variables from the middle of the statement without having to change all the other coefficients.

However, this might be a little less obvious to the reader.

Upvotes: 5

Mark Byers
Mark Byers

Reputation: 839194

You might find it clearer to use bitwise operators instead of multiplication and addition:

int val = (boolVal1 << 2) | (boolVal2 << 1) | boolVal3; 

Upvotes: 27

Related Questions