In the sketch I'm working on, I'm storing several 1-bit values representing different boolean states in a single byte, trying to save precious RAM. (example for 5 boolean states: `dec10` = `b00001010`, the five states are `0`, `1`, `0`, `1`, `0`)

I'm then using an `if` statement to determine if the relevant bit is `TRUE` or `FALSE`:
`if ((options>>3) & 1 == 1)`

The above will evaluate `true` when the relevant bit is `1`, so if I want to carry out something in that case, great, no problem!

However, if I want my `if` statement to evaluate `TRUE` in the event that the relevant bit is `0`, I can't work out what code I need.

I thought the problem might be that the other 'non-relevant' bits were interfering, so I tried bit shifting the LSB all the way to MSB position and then shifting back to LSB:
`if ((options<<4>>7) & 1 == 0)`
but this still isn't doing what I'm trying to achieve (and seems like a lot of work for the processor).

It also feels like I've tried just about every combination of `~&0`, `!&0`, `==0`, `!=0`, `~&1`, `!&1`, `==1`, `!=1` there is, but I must have missed something...

Can anyone tell me how I get an if statement to evaluate true in the event that the bit is a zero?

• Welcome to Arduino:SE. You might find this helpful: How to ask a good question for Arduino Stack Exchange Apr 24, 2018 at 22:23
• `if ((options>>3) & 1 == 0)` or `if ((options>>3) & 1 != 1)` - if neither of them work, you did something wrong Apr 24, 2018 at 23:51

The simplest thing is just to mask an individual bit, not do any shifting:

``````if (options & 0x04) {
// Do something if true
} else {
// Do something if false
}
``````

Or, to invert it:

``````if (!(options & 0x04)) {
// Do something if false
} else {
// Do something if true.
}
``````

The thing with C is that 0 is false, and anything else is true. So if your `options` variable contains `0b00001010` and you AND it with 0x04 (which is HEX for `0b00001000`) you end up with `0b00001000`. That is 0x04, which is something other than 0, so it's true.

If `options` contains `0b00000010` and you AND it with 0x04, you get `0b00000000`, which is 0. Since 0 is false the result is false.

You don't care what the actual number is - you only care if it's 0.

• This is exactly what I needed, the exclamation mark goes to the left of the statement being evaluated, thanks @Majenko. You've also taught me a much better way of singling out the bit I'm interested in, perfect! Apr 24, 2018 at 22:51
• for readibility add a definition like `#define myImportantOption 0x04` ..... then use `if (options & myImportantOption) {` .......... put all the definitions at the beginning of your program, so that you can easily change them if you use a different arduino that may have status bits in a different location Apr 25, 2018 at 0:40
• @jsotola - good advice for code readability and portability. Would this make any difference to what the ATMEGA sees, or are differences such as this all compiled identically before upload? Apr 25, 2018 at 17:12

There is an alternative to doing bit shifts, and that is to use the `bit` macro which is defined in Arduino.h (and thus is automatically available).

``````#define bit(b) (1UL << (b))
``````

Now if you want to see if the second bit is set (which as a mask would be 0x04, being 1 shifted left 2 times) you can do this:

``````if (options & bit (2))
{
// bit number 2 is set
}
else
{
// bit number 2 is clear
}
``````

This is easier to read than:

``````if (options & (1 << 2))
``````

or:

``````if (options & 0x04)
``````

And to invert it:

``````if (!(options & bit (2)))
{
// bit number 2 is clear
}
``````

Or:

``````if ((options & bit (2)) == 0)
{
// bit number 2 is clear
}
``````

Also, the various processor bits are given as bit numbers in the Atmega include files (rather than bit masks). So, for example, to set some processor bits you can do this:

``````WDTCSR |= bit (WDCE) | bit (WDE);
``````

That is easier to read than:

``````WDTCSR |= (1 << WDCE) |  (1 << WDE);
``````

And much easier than turning them into hex numbers:

``````WDTCSR |= 0x10 | 0x08;
``````

And in case you are wondering how to clear a bit, you and in the 1s complement:

``````WDTCSR &= ~bit (WDCE);
``````
• What’s wrong with the `_BV()` macro that’s already included? Apr 25, 2018 at 14:49
• @Nick - `bit` is new to me, makes things very easy to read, thank you Apr 25, 2018 at 17:30
• @Gerben Because identifiers starting with an underscore and followed by an uppercase letter are reserved and should not be used. For example Identifiers (C++). Use of two sequential underscore characters ( __ ) at the beginning of an identifier, or a single leading underscore followed by a capital letter, is reserved for C++ implementations in all scopes. You should avoid using one leading underscore followed by a lowercase letter for names with file scope because of possible conflicts with current or future reserved identifiers. Apr 25, 2018 at 21:00
• @Gerben As I pointed out the `bit()` macro is also already included. I quoted the file it is in (Arduino.h) which will be present in all attempts to compile with the IDE. Apr 25, 2018 at 21:00
• @Gerben - the compiler may never "see" it, but let's assume that one day the compiler-writers decide to use `_BV` for some internal construct (as they are permitted to do, as it is reserved), and the macro form of `_BV` in Arduino.h overrides that. The compiler will see the difference and not work correctly. Apr 28, 2018 at 1:32