In this article we are going to use Scilab to perform logic operations with Boolean variables and bitwise operation with integer variables. To get a basic understanding on the logic operations (logic gates) read the article Logical operations and boolean functions.

Scilab has three elementary functions defined for logical operations.

Keyword | Name | Description |

`~` | Logical NOT operator | Gives the element-wise negation of a Boolean variable |

`&` | Logical AND operator | Gives the element-wise logical AND of two Boolean variables |

`|` | Logical OR operator | Gives the element-wise logical OR of two Boolean variables |

To use the elementary logical operators, let’s define two Boolean variables `A`

and `B`

.

`-->A = %T;`

`-->B = %F;`

Applying the logical NOT to the `A`

variable gives:

`-->~A`

`ans =`

` F`

As expected, the negation of a true variable (`%T`

) will output a false value (`%F`

).

Applying the logical AND to the Boolean variables `A`

and `B`

, gives:

`-->A & B`

`ans =`

` F`

Applying the logical OR to the Boolean variables `A`

and `B`

, gives:

`-->A | B`

`ans =`

`T `

To exercise the complete truth tables for the basic logic operations (gates), we are going to define the Boolean variables `A`

and `B`

as vectors of logic states:

`-->A = [%F; %F; %T; %T];`

`-->B = [%F; %T; %F; %T];`

### NOT gate

We are going to apply the NOT gate only to the variable `A`

, as:

`-->~A`

`ans =`

` T `

` T `

` F `

` F `

### AND gate

In Boolean algebra, the logic operation AND between two variables `A`

and `B`

, is represented as:

The Scilab AND operation between `A`

and `B`

is:

`-->A & B`

`ans =`

` F `

` F `

` F `

` T `

### OR gate

In Boolean algebra, the logic operation OR between two variables `A`

and `B`

, is represented as:

The Scilab OR operation between `A`

and `B`

is:

`-->A | B`

`ans =`

` F `

` T `

` T `

` T `

### NAND gate

In Boolean algebra, the logic operation NAND between two variables `A`

and `B`

, is represented as:

The Scilab NAND operation between `A`

and `B`

is:

`-->~(A & B)`

`ans =`

` T `

` T `

` T `

` F `

### NOR gate

In Boolean algebra, the logic operation NOR between two variables `A`

and `B`

, is represented as:

The Scilab NOR operation between `A`

and `B`

is:

`-->~(A | B)`

`ans =`

` T `

` F `

` F `

` F `

### XOR gate

In Boolean algebra, the logic operation XOR between two variables `A`

and `B`

, is represented as:

The Scilab XOR operation between `A`

and `B`

is:

`-->(A & (~B)) | ((~A) & B)`

`ans =`

` F `

` T `

` T `

` F `

### XNOR gate

In Boolean algebra, the logic operation XNOR between two variables `A`

and `B`

, is represented as:

The Scilab XNOR operation between `A`

and `B`

is:

`-->(A & B) | ((~A) & (~B))`

`ans =`

` T `

` F `

` F `

` T `

All the above operations can be summarized in a Scilab script file, as:

clc A = [%F; %F; %T; %T]; B = [%F; %T; %F; %T]; Q_NOT = ~A; Q_AND = A & B; Q_OR = A | B; Q_NAND = ~(A & B); Q_NOR = ~(A | B); Q_XOR = (A & (~B)) | ((~A) & B); Q_XNOR = (A & B) | ((~A) & (~B)); disp("A B AND OR NAND NOR XOR XNOR") disp([A B Q_AND Q_OR Q_NAND Q_NOR Q_XOR Q_XNOR])

Executing the script file (Scilab instructions) will output in the Scilab console:

` A B AND OR NAND NOR XOR XNOR `

` F F F F T T F T `

` F T F T T F T F `

` T F F T T F T F `

` T T T T F F F T`

### Bitwise operations – predefined Scilab functions

In computer engineering, IT, embedded systems, control engineering, software engineering, bitwise operations are a common practice. **Bitwise operations** means performing logic operation on bits (`0`

and `1`

) rather than logic states `true`

or `false`

.

A decimal number can be converted to a binary number. For example, decimal `53`

is `00110101`

in binary. We can easily do the conversion with the Scilab function `dec2bin()`

.

`-->dec2bin(53,8)`

`ans =`

` 00110101`

Let’s consider a second decimal number, `92`

, converted in binary will give `01011100`

.

`-->dec2bin(92,8)`

`ans =`

` 01011100`

Performing a bitwise operation between `53`

and `92`

means performing a logic operation between their binary representation. For example a **bitwise OR** will give:

53 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 |

OR | `|` | |||||||

92 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 0 |

125 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |

The bitwise OR means performing an OR operation between corresponding bits, from bit 0 to bit 7. The result will be `01111101`

, which converter in decimal is `125`

. We can easily verify the result with a Scilab operation:

`-->uint8(53) | uint8(92)`

`ans =`

` 125 `

`-->dec2bin(125,8)`

`ans =`

` 01111101 `

Notice that the decimal numbers were defined as 8 bit integers, using the Scilab function `uint8()`

.

There are some Scilab predefined functions for bitwise operations:

`bitand()`

– performs bitwise AND`bitor()`

– performs bitwise OR`bitxor()`

– performs bitwise XOR

The way to use them is by defining the decimal numbers as vectors of integer binary values. For example, decimal variable `A`

, equal with `53`

, and decimal variable `B`

, equal with `92`

, will be written as:

`-->A = [0 0 1 1 0 1 0 1];`

`-->B = [0 1 0 1 1 1 0 0];`

To perform a bitwise OR, with the result stored in a variable `Q`

, we have to execute in the Scilab console:

`-->Q = bitor(A,B)`

`Q =`

` 0. 1. 1. 1. 1. 1. 0. 1. `

The main disadvantages of using the predefined Scilab functions for bitwise operations are that:

- we need to define the “binary” value as a vector of
`0`

and`1`

- we need to use string processing function to convert back to a decimal value

For example, to get the decimal value from the `Q`

variable, we have to use:

`-->bin2dec(strcat(string(Q)))`

`ans =`

` 125. `

This is good but we can do better.

### Bitwise operations – custom Scilab functions

We are going to define a custom Scilab function, which has to fulfill the following requirements:

- it has to perform the following bitwise operations: AND, OR, NAND, NOR, XOR, XNOR
- between two unsigned integer decimal variables defined on either 8, 16, 32 or 64 bits

The function is going to be called `bitwise()`

, with the following source code:

function y = bitwise(A,B,gateType) dataType_A = typeof(A); dataType_B = typeof(B); if (dataType_A ~= dataType_B) then error("ERROR: The input variables do not have the same data type!") end if and(gateType ~= ["AND" "OR" "NAND" "NOR" "XOR" "XNOR"]) then error("ERROR: The gate type must be either: AND, OR, NAND, NOR, XOR or XNOR"); end select dataType_A case "uint8" bitNo = 8; case "uint16" bitNo = 16; case "uint32" bitNo = 32; case "uint64" bitNo = 64; else error("ERROR: The input variables must be either: uint8, uint16, uint32 or uint64"); end select gateType case "AND" Q = dec2bin(A & B, bitNo); case "OR" Q = dec2bin(A | B, bitNo); case "NAND" Q = dec2bin(~(A & B), bitNo); case "NOR" Q = dec2bin(~(A | B), bitNo); case "XOR" Q = dec2bin((A & (~B)) | ((~A) & B), bitNo); case "XNOR" Q = dec2bin((A & B) | ((~A) & (~B)), bitNo); end y = Q; endfunction

To define and load the function in Scilab, open a new file in SciNotes, copy the above source code, save the file as `bitwise.sci`

and execute it. If everything is successful, you’ll see in the Scilab console a message similar with:

`-->exec('some_folder_path/bitwise.sci', -1)`

Let’s go through the function step by step.

The function expects three arguments:

`A`

– unsigned integer decimal value; minimum value is`0`

, maximum is`2`

.^{52}`B`

– unsigned integer decimal value; minimum value is`0`

, maximum is`2`

.^{52}`gateType`

– string defining which bitwise operation will be performed; it can take only the following values:`AND`

,`OR`

,`NAND`

,`NOR`

,`XOR`

,`XNOR`

.

At the beginning, the function extracts the data type of the input decimal values, using the Scilab function `typeof()`

. After, a data consistency check is performed, both decimal values have to have the same data type. Otherwise an error message is displayed.

Another check is for the `gateType`

. It makes sure that the user has entered only a supported bitwise function, otherwise an error message is displayed.

The next instructions are checking the data type of the variable `A`

(which is the same with variable `B`

) and assigns the right number of bits using the local variable `bitNo`

. This variable is going to be used further in the bitwise operations. In case of a wrong data type, an error message is displayed.

Function of the `gateType`

, the corresponding bitwise operation is executed.

The result is stored in the local variable `Q`

, which is passed to the function output `y`

as a string.

Let’s test out function, first by triggering the wrong data type check.

`-->bitwise(53,92,'OR')`

`!--error 10000`

` ERROR: The input variables must be either: uint8, uint16, uint32 or uint64`

` at line 20 of function bitwise called by :`

` bitwise(53,92,'OR')`

As expected, the user is informed that the data type of the input variables is not the expected one. In our example they are `Double`

by default and the function expects unsigned integers (8, 16, 32 or 64 bit).

Let’s try now different data types for the input variables:

`-->bitwise(uint8(53),uint16(92),'OR')`

`!--error 10000 `

`ERROR: The input variables do not have the same data type!`

`at line 5 of function bitwise called by : `

`bitwise(uint8(53),uint16(92),'OR')`

As expected, the user is informed that the input variables don’t have the same data type. Variable `A`

(`53`

) is `uint8`

, while variable `B`

(`92`

) is `uint16`

.

The last check is for an undefined or misspelled bitwise operation.

`-->bitwise(uint8(53),uint8(92),'OT')`

`!--error 10000 `

`ERROR: The gate type must be either: AND, OR, NAND, NOR, XOR or XNOR`

`at line 8 of function bitwise called by : `

`bitwise(uint8(53),uint8(92),'OT')`

Let’s enter the function arguments in the right format, for the same decimal values and bitwise function used in the previous example:

`-->bitwise(uint8(53),uint8(92),'OR')`

`ans =`

` 01111101 `

To get the decimal value we can apply the `bin2dec()`

function to the `ans`

variable

`-->bin2dec(ans)`

`ans =`

` 125.`

or use the whole instruction as an argument for the `bin2dec()`

function.

`-->bin2dec(bitwise(uint8(53),uint8(92),'OR'))`

`ans =`

` 125.`

We can also input, as `bitwise()`

function arguments, the corresponding binary string of our decimal variable as arguments for the `bin2dec()`

function.

`-->bitwise(uint8(bin2dec("00110101")),uint8(bin2dec("01011100")),'OR')`

`ans =`

` 01111101 `

Let’s use the function for a 32 bit input variables and a bitwise XOR logic operation:

`-->bitwise(uint32(127635243),uint32(273825354),'XOR')`

`ans =`

` 00010111110010011011000101100001 `

For a better understanding of logic gates and bitwise operations, let’s call our `bitwise()`

function in a Scilab script, which goes through all the defined bitwise operations, for a given set of input variables.

clc A = uint32(127635243); B = uint32(273825354); logicGates = ["AND" "OR" "NAND" "NOR" "XOR" "XNOR"]; printf("\nA\t=\t%s",dec2bin(A,32)); printf("\nB\t=\t%s",dec2bin(B,32)); for i=1:max(size(logicGates)) Q = bitwise(A,B,logicGates(i)); printf("\n%s\t=\t%s",logicGates(i),Q); end

Running the Scilab intructions above, will give the following output in the Scilab console:

`A = 00000111100110111000111100101011`

`B = 00010000010100100011111001001010`

`AND = 00000000000100100000111000001010`

`OR = 00010111110110111011111101101011`

`NAND = 11111111111011011111000111110101`

`NOR = 11101000001001000100000010010100`

`XOR = 00010111110010011011000101100001`

`XNOR = 11101000001101100100111010011110 `

For any questions or observations regarding this tutorial please use the comment form below.

Don’t forget to Like, Share and Subscribe!