← Back to the index page

Bitwise operations in Lua

Tip

Bitwise operators: &, |, ~, >>, << were presented since Lua 5.3. In Lua 5.2, there is a bit32 module. In Lua 5.1 an extra library like this one should be installed.

Bitwise operations in Lua are the same as bitwise operations in C.

Bits and bytes

Bitwise operations are the operations on bits. Each byte consists of 8 bits, which can have values only 1 or 0, called a binary number.

Byte 1 0000 0000
Byte 2 0001 0100
Byte 3 0001 0100
Byte 4 1111 1100
...

Binary numbers

A binary number is a number expressed in the base-2 numeral system or binary numeral system, used in computer science.

DecimalBinaryOctalHexadecimal
0000
1111
21022
31133
410044
510155
611066
711177
81000108
91001119
10101012A
11101113B
12110014C
13110115D
14111016E
15111117F

Table 1. The first 16 numbers in various number systems.

Bit numbering

Bits in the byte are placed in definite order, like the numbers in decimal system. The less meaningful bit is placed at the right side. The least significant bit (LSb) is placed from the right side, and correspondingly, the most significant bit (MSb) is from the left side.

87654321 order
00000000 bits

Bitwise operations

Usually bitwise operations are not widely used in scripting languages, like Lua or JavaScript. Developers who is writing scripts usually not very familiar with bits, because there is no need to dive so deeply into low level. Sometimes bits might be very useful and make code shorter and reduce memory usage. From the other side, overusing bitwise operators might lead to cryptic and hardly maintainable code. This tool should be used wisely.

Tip

There might be differences in 32-bit and 64-bit systems; be sure that your final code will run on the same system; otherwise, it might lead to unexpected results.

Lua (since 5.3) has in-built the following bitwise operators:

Bitwise AND &

21 & 19 --> 17

The bitwise AND operation compares two binary numbers bit by bit and returns a new number where each bit is set to 1 only if both corresponding bits of the operands are 1; otherwise, the resulting bit is set to 0.

  00010101 (decimal 21)
& 00010011 (decimal 19)
-----------
  00010001 (decimal 17)

Bitwise OR |

21 | 19 --> 23

The bitwise OR operation compares two binary numbers bit by bit and returns a new number where each bit is set to 1 if either of the corresponding bits in the operands is 1. If both bits are 0, the result is 0.

  00010101 (decimal 21)
| 00010011 (decimal 19)
-----------
  00010111 (decimal 23)

Bitwise XOR ~

21 ~ 19 --> 6

The bitwise XOR (exclusive OR) operation compares two binary numbers bit by bit and returns a new number where each bit is set to 1 if the corresponding bits of the operands are different. If both bits are the same (either both 0 or both 1), so the result is 0.

  00010101 (decimal 21)
~ 00010011 (decimal 19)
-----------
  00000110 (decimal 6)

Bitwise NOT ~

~21 --> -22

The bitwise NOT inverts bits zeros into ones and vice versa. Do not be confused with XOR ~, which is applied to two operands, but unary NOT to only one number.

~ 00010101 (decimal 21)
-----------
  11101010 (decimal signed -22, unsigned 234*)

Tip

By default, in Lua numbers are signed, unless it is compiled to use unsigned integers. The 8th bit means for number 0 - positive, 1 for negative numbers; this is why in the upper example signed is equal to -22.

Bitwise left << and right >> shift

21 << 2 --> 84
21 >> 3 --> 2

Bitwise shift operations move the bits of a number to the left or right by a specified number of positions. Both right and left shifts fill the vacant bits with zeros. Negative displacements shift to the other direction; displacements with absolute values equal to or higher than the number of bits in an integer result in zero (as all bits are shifted out).

Left shift:

   00010101 (decimal 21)
<<        2
------------
   01010100 (decimal 84)

Right shift:

```text
   00010101 (decimal 21)
>>        3
------------
   00000010 (decimal 2)

Logical equivalents

Four of the bitwise operators have equivalent logical operators.They are equivalent in that they have the same truth tables. However, logical operators treat each operand as having only one value, either true or false, rather than treating each bit of an operand as an independent value. Also, logical operations performs short-circuit evaluation.

BitwiseLogical
a & ba and b
a | ba or b
a ^ ba ~= b
~anot a

Some applications of bitwise operations

Here are some examples of how bitwise can be used in the daily job.

Check that number is odd or even

2 & 1 == 0     -- even
12 & 1 == 0    -- even
444 & 1 == 0   -- even
1 & 1 == 1     -- odd
3 & 1 == 1     -- odd
123 & 1 == 1   -- odd
-- and so on.

We are interested only in the 1st bit: is this 0 or 1. If both bits are 1, then the number is always odd. From the examples below everything becomes much clearer:

  00000010 (decimal 2)
& 00000001 (decimal 1)
-----------
  00000000 (decimal 0)
  Result is 0, thus 2 is even.
  00001110 (decimal 14)
& 00000001 (decimal 1)
-----------
  00000000 (decimal 0)
  Result is 0, thus 14 is even.
  00000111 (decimal 7)
& 00000001 (decimal 1)
-----------
  00000001 (decimal 1)
  Result is 1, thus 7 is odd.

Bit flags

Another widely used case for bitwise operations is the permissions pattern. It is very common in C to set permission for a file access using bits.

Consider:

-- power of 2
local READ = 1
local WRITE = 2
local EXEC = 4

function open(filename, mode)
  if mode & READ == 1 then
    -- can read file
  end
  if mode & WRITE == 1 then
    -- can write to file
  end
  if mode & EXEC == 1 then
    -- can execute a file
  end
end

-- Can read, write, execute
open("poetry.sh", READ | WRITE | EXEC)

Explanation:

  00000001 (READ 1)
| 00000010 (WRITE 2)
| 00000100 (EXEC 4)
-----------
  00000111 (7)

Read

  00000111 (7)
& 00000001 (1)
-----------
  00000001 (Can read)

Write

  00000111 (7)
& 00000010 (2)
-----------
  00000010 (Can write)

Execute

  00000111 (7)
& 00000100 (4)
-----------
  00000100 (Can execute)

Memory management

Using Lua for programming IoT and microcontrollers where memory is very limited. However, this topic falls outside the purview of this discussion this article.

References

Feedback

For feedback, please check the contacts section. Before writing, please specify where you came from and who you are. Sometimes spammers go insane. Thank you in advance for your understanding.

← Back to the index page