A
A
Anton Shamanov2021-12-06 04:58:05
Mathematics
Anton Shamanov, 2021-12-06 04:58:05

How to check if a bitmask is valid?

Example:
There are "flags": a = 1, b = 2, c = 6
The value must be a bitmask containing 1 to 3 flags:
a, b, c
a | b, a | c, b | c
a | b | c

How can I check the value? for example, 7 is true (a | c) but 4 or 11 is not true.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
R
Rsa97, 2021-12-06
@SilenceOfWinter

You don't have a bitmask because b and c contain the same bit 2 and it's impossible to tell c from b|c. 2|6 === 6. In the bitmask, all unique non-combined flags must be powers of two.
You can work with your set, but you will have to add the flags through +, and check with your own function, like this:

function flags($value) {
    if (!in_array($value, [0, 1, 2, 3, 6, 7, 8, 9])) {
        return false;
    }
    $result = [];
    if (in_array($value, [1, 3, 7, 9])) {
        $result[] = 'a';
    }
    if (in_array($value, [2, 3, 8, 9])) {
        $result[] = 'b';
    }
    if (in_array($value, [6, 7, 8, 9])) {
        $result[] = 'c';
    }
    return $result;
}

D
dollar, 2021-12-06
@dollar

The validity of a bitmask is usually not checked because there are usually no normal criteria. Essentially, each flag is a power of two (or a separate "bit"). So the correct mask is just a number between 0 and the maximum possible when all flags are on. There are usually no holes in this range. For clarity, try to write the mask in binary format.
Suppose you have five "flags": a=1, b=2, c=4, d=8, e=16,
then the mask value will be from 0 to 31 (i.e. max. 11111). By going out of range, we can say that it is incorrect . But if you have 32 flags in a mask of type uint, then going beyond the range is not possible in principle, and any mask will be correct.
Suppose you now have 4 flags: a=1, b=2, d=8, e=16,
that is, c=4 is missing. Then it's like a hole in the mask.
Check this bit: (mask & 4 == 4)
In theory, if this bit is set, then the mask is incorrect. But on the other hand, the target algorithm can simply ignore the bit that is not used. So the extra bits don't make the mask invalid.
And, finally, a real criterion is already possible, when the logic of the flags is such that not all combinations are possible. Although it is better not to solve such cases at all with flags, nevertheless it happens. For example, it is forbidden to set b=2 and e=16 at the same time, then the invalidity condition will be the following:
(mask & 2 > 0) && (mask & 16 > 0)
Or, in short:
(mask & (b | e) > 0)
(mask & 18 > 0)
Similarly, any other condition imposed on the mask is checked. For example, if the number of enabled flags is limited, then we simply count the number of bits in the mask.
PS And yes, c=6 is an invalid flag, because it contains b=2, and you can't tell if mask=c or mask=b|c.

V
Vasily Melnikov, 2021-12-06
@BacCM

You can AND all the inverted flag values ​​​​and if it is not 0, then there is an extra "wrong" bit
In C

size_t value = // Откуда-то получили

bool isValid = (value & ~(MASK1 | MASK2 | MASK3)) == 0;

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question