Embedded Wednesdays: Logic in C Part I

Last week at the ENTS Embedded Wednesdays get together, Andrew asked me about the bit manipulation and and or operators in C, and when anybody would ever use them for real. To answer the question about bit manipulation, I thought that a short review of the logical operations was in order, just to give some context to work with. This week’s post is all about boolean values and the logical operations, and next week I’ll explain bit manipulations.

Boolean values in C

Computer languages support a data type called a boolean, that will hold a value of either true or false.

In our first example, we will create two boolean values and show two ways of assigning values to them. The first shows direct assignment of the values true and false. The second shows assignment of the result of a comparison operation:

#include <stdbool.h>       // Gives the true and false symbols
#include <iso646.h>        // Gives the and and or symbols
#include <stdint.h>        // Gives the uint32_t symbol
int32_t main( void) {
   /*
    * No, this isn’t a complete program. We’re just showing
    * fragments today.
    */
   bool sampleIsHot;
   bool sampleIsBurnt;
   uint32_t temperature

   SensorGetReading( temperature);

   if (temperature > 165) {   
   sampleIsHot = true;                    // Direct assignment 
   } else {
      sampleIsHot = false;
   }
   sampleIsBurnt = (temperature > 400);   // Result of a comparison 
}

Booleans are used with looping statements (do, for, while) and conditionals (if).

if (sampleIsBurnt) {
   SampleDispose();
}

while (sampleIsHot == false) {
   SampleIrradiate();
   ...
   if (temperature > 165) {
      sampleIsHot = true;
   ...
  }
}

Boolean operations

Most computer languages give you some basic manipulations that can be applied to booleans to make them useful beyond controlling loops.

The most basic boolean operation is known as logical negation where true becomes false, and false becomes true. In C, logical negation uses the ! character:

sampleIsReady = false;            // initialize to false
temperature = 451;
...
if (temperature > 400) {
   sampleIsReady = !sampleIsReady;    // negate, becomes true
}

Things get a little more interesting when you have two boolean values. The basic operations on two boolean values are and and or.  C  has some funky syntax for and and or, it uses && and || (two vertical bar characters) respectively. You are free to use these, but the header file iso646.h gives you #defines so that you can use and and or in your code. For my blog posts, as well as my code in real life, I will be using and and or.

The and operation takes two boolean values and combines them so that the result will be true if both the first value and the second value are true.

if (isMorning and !isWeekend) {
   GetUp( andrei);
}

This is the same as:

if (isMorning && !isWeekend) {
   GetUp( andrei);
}

The or operation takes two boolean values and the result will be true if the first or second value is true.

if ((time > 17) or (temperature >= 25)) {
   GoHome( andrei);
}

This is the same as:

if ((time > 17) || (temperature >= 25)) {
   GoHome( andrei);
}

Truth Tables

One way of showing the boolean operations in a easily digestible way is truth tables. For these tables I will use the variables A and B. In each column will be the values of A and B and the result column gives the result of the operation.

First negation. Negation only uses one variable. As you can see from column A, it has two values, true and false. After applying the negation operation, we get the negated values in the result column.

Negation

A !A
TRUE FALSE
FALSE TRUE

Next and. The result is true if both A and B are true. Notice that the table has all combinations of A and B.

And

A B A and B
TRUE TRUE TRUE
FALSE TRUE FALSE
TRUE FALSE FALSE
FALSE FALSE FALSE

Finally or. The result is true if either A or B is true.

Or

A B A or B
TRUE TRUE TRUE
FALSE TRUE TRUE
TRUE FALSE TRUE
FALSE FALSE FALSE

It is very valuable to understand what and and or do as phrases in English. I once worked at a bank where a programmer had a weird bug. They explained to me what their program was intended to do and what it was actually doing, and said that the computer was broken because the and instruction wasn’t working. The problem was that their truth table, pinned up on their cubicle, had and and or backwards. They didn’t actually understand what and and or were doing, they just followed their backwards truth tables.

Combinations

There will be situations where you will need to use a combination of ands, ors, and negations to control your program. You may find boolean functions such as DeMorgan’s law useful to simplify these cases.

If you’re an Electrical Engineer, you may have dealt with Karnaugh maps for random logic circuits. These are directly mappable into the three basic operations.

Please use round brackets to make the order of operations explicit. The programmer that follows will thank you.

if ((temperature > 0) and
   ((temperature < 42) or (temperature >= 100))) {

Those are the basics of boolean logic in C for embedded systems. In the next installment, we will be looking at logic manipulation at the bit level and when you would want to do that.


This post is part of a series. Please see the other posts here.


 A Texas Instruments SN74HC32N quad 2 input OR gate.

A Texas Instruments SN74HC32N quad 2 input OR gate.