4

Often in my code I need to check whether the state of x amount of bools are all true OR all bools are false. So I do:

BOOL first, second, third;
if((first && second && third) || (!first && !second && !third))
     //do something

Being a lazy programmer, I want to know if there is some mathematical shorthand for this kind of query, instead of having to type out this whole thing every time?

Snowman
  • 31,411
  • 46
  • 180
  • 303
  • I'm pretty sure that is the only way to express that using standard boolean logic operators. Do you want to do this in some particular language? Some languages have shorthand methods for stuff like this – murgatroid99 Aug 26 '12 at 16:41
  • There is in Predicate Logic, if all of the elements are in a distinct set. – RBarryYoung Aug 26 '12 at 16:41
  • If this bothers you, write your own function (or macro) for it! – Sulthan Aug 27 '12 at 07:52

4 Answers4

5

The shorthand for all bools the same is testing for (pairwise) equality:

(first==second && second==third)

Of course you can expand this to any number of booleans, having N-1 equality checks joined with the and operator.

Howard
  • 38,639
  • 9
  • 64
  • 83
3

If this is something you frequently require then you're better off using an integer and reading bits individually.

For instance, instead of:

BOOL x; // not this
BOOL y; // not this
BOOL z; // not this

...and instead of bit fields (because their layout is implementation-defined):

unsigned int x : 1; // not this
unsigned int y : 1; // not this
unsigned int z : 1; // not this

...use a single field such as:

unsigned int flags; // do this

...and assign every value to a bit; for example:

enum { // do this
  FLAG_X = (1 << 0),
  FLAG_Y = (1 << 1),
  FLAG_Z = (1 << 2),
  ALL_FLAGS = 0x07 // "all bits are on"
};

Then, to test "all false" you simply say "if (!flags)" and to test "all true" you simply say "if (flags == ALL_FLAGS)" where ALL_FLAGS is a number that sets all valid bits to 1. Other bitwise operators can be used to set or test individual bits as needed.

Note that this technique has an upper limit of 32 Boolean values before you have to do more (e.g. create an additional integer field to store more bits).

Kevin Grant
  • 5,363
  • 1
  • 21
  • 24
  • Interesting technique..I'm not very familiar with what you're doing with the enum part..so an int has...32 bits? and by doing 1 << x, you get the x'th bit? What about 0x07? – Snowman Aug 27 '12 at 03:03
  • An integer is usually at least 32 bits, though this varies by architecture. (Using `` and the type `uint32_t` is a good way to know for sure that a variable is at least that size.) The enumerations can be defined in various ways; my goal is to choose values that differ by only one bit, so 1, 2, 4, ... and I find it clearest to do that using shift operators. Similarly, `0x07` just means `7` (which in binary is `111`; my goal was to set all bits to 1). – Kevin Grant Aug 27 '12 at 23:35
  • Any idea where I can read more about what you're talking about? – Snowman Aug 28 '12 at 00:44
  • I'm not sure of a good reference for it...I learned this particular thing years ago by example (as Apple's Mac OS APIs tended to use this approach). Most of it is just C language features though; `<<` is the left-shift operator, anonymous `enum` is just one of several ways to define integer constants, `0x...` means "hexadecimal number", and in my counterexample `: 1` is an example of C's bit field syntax (the results of which are compiler-defined). – Kevin Grant Aug 28 '12 at 02:34
2

Check if the sum is 0 or equal to the number of bools:

((first + second + third) % 3 == 0)

This works for any number of arguments.

(But don't take this answer serious and do it for real.)

Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
  • 2
    Using this on BOOLs is absolutely evil. Recommended only to obfuscate your code. – Sulthan Aug 26 '12 at 18:07
  • 1
    @mohabitar Because it hides the meaning of your code. It's like asking "Does the remainder of the sum of you who wants ice cream and the total number of children equal zero?" instead of "Everybody want's ice cream?". I meant it as a joke. Obviously some people still feel offended. – Nikolai Ruhe Aug 26 '12 at 18:20
1

When speaking about predicates, you can usually simplify the logic by using two variables for the quantification operations - universal quantification (for all) and existential quantification (there exists).

BOOL allValues = (value1 && value2 && value3);
BOOL anyValue = (value1 || value2 || value3);

if (allValues || !anyValue) {
   ... do something
}

This would also work if you have a lot of boolean values in an array - you could create a for cycle evaluating the two variables.

Sulthan
  • 128,090
  • 22
  • 218
  • 270