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?

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! – Cammack Apr 24 '18 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 – jsotola Apr 25 '18 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? – Cammack Apr 25 '18 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? – Gerben Apr 25 '18 at 14:49
• @Nick - `bit` is new to me, makes things very easy to read, thank you – Cammack Apr 25 '18 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. – Nick Gammon Apr 25 '18 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. – Nick Gammon Apr 25 '18 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. – Nick Gammon Apr 28 '18 at 1:32