简体   繁体   中英

Most efficient way to check if flags are set in an integer

I have 11 flags defined as:

#define F1 1
#define F2 2
#define F3 3
#define F4 4
...
#define F11 11

In some function I then create an integer which can include either of those flags, for example:

int a = (1 << F1) | (1 << F5) | (1 << F11) | (1 << F8);

This then gets passed into a function which needs to decode which flags are set in order to set specific bits in specific registers. So my question is, what is the most efficient way to check which flags are set. Right now I have 11 if's like:

void foo(int a) 
{
    if ((a & (1 << F1)) >> F1) {
        // Set bit 5 in register A.
    }

    if ((a & (1 << F2)) >> F2) {
        // Set bit 3 in register V.
    }

    if ((a & (1 << F3)) >> F3) {
        // Set bit 2 in register H.
    }

    if ((a & (1 << F4)) >> F4) {
        // Set bit 1 in register V.
    }

    // And so on, for all 11 flags.
}

PS This is for an 8-bit microcontroller.

C's if statement and logical operators do not make a difference between 1 and other non-zeros (although logical operators produce 1 for true ). Therefore, there is no difference between (a & (1 << F3)) >> F3 and a & (1 << F3) in the context of a logical expression: if one evaluates to true , so does the other one, and vice versa. Hence, this should work:

if (a & (1 << F1)) {
    // Set bit 5 in register A.
}

Note: I assume you didn't mean to write #define F11 1024 , but rather #define F11 10 , because you use your F s as the second operand of << .

Just use:

typedef enum{
    FLAG1 = 1, // or 0x01
    FLAG2 = 2,
    FLAG3 = 4,
    ...
    FLAG8 = 0x80
} flags;

Then in main just check

if(value & FLAGN)

In C there is no diffrence between 1 and any other number in if statement. It just check if is zero or non-zero number.

And setting is the same:

value = FLAG1 | FLAG2 | FLAG8;

You can also use defines ofc.

And for claryfication, max number of flags for N bit type is N. So you need to have larger type (if compiller supports bigger datatypes) like uint16_t.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM