Lua - Operators

Overview

Estimated time: 25–30 minutes

Operators are symbols that perform operations on operands. Lua provides various types of operators for arithmetic, comparison, logical operations, and more. This tutorial covers all operator types with practical examples.

Learning Objectives

  • Master arithmetic operators for mathematical calculations
  • Understand relational operators for comparisons
  • Learn logical operators for boolean logic
  • Explore miscellaneous operators like length and concatenation
  • Apply operator precedence rules correctly

Prerequisites

  • Understanding of Lua data types
  • Knowledge of variables and basic syntax

Arithmetic Operators

Arithmetic operators perform mathematical operations on numbers:

Operator Description Example
+ Addition 5 + 3 = 8
- Subtraction 10 - 4 = 6
* Multiplication 6 * 7 = 42
/ Division 15 / 3 = 5.0
// Floor Division 17 // 5 = 3
% Modulo 17 % 5 = 2
^ Exponentiation 2 ^ 3 = 8
- Unary Minus -5 = -5

Arithmetic Examples

local a = 15
local b = 4

print("Addition:", a + b)        -- 19
print("Subtraction:", a - b)     -- 11
print("Multiplication:", a * b)  -- 60
print("Division:", a / b)        -- 3.75
print("Floor Division:", a // b) -- 3
print("Modulo:", a % b)          -- 3
print("Exponentiation:", a ^ 2)  -- 225
print("Unary Minus:", -a)        -- -15

-- Working with floats
local x = 10.5
local y = 3.2
print("Float division:", x / y)   -- 3.28125
print("Float modulo:", x % y)     -- 1.1

Expected Output:

Addition:	19
Subtraction:	11
Multiplication:	60
Division:	3.75
Floor Division:	3
Modulo:	3
Exponentiation:	225
Unary Minus:	-15
Float division:	3.28125
Float modulo:	1.1

Relational Operators

Relational operators compare values and return boolean results:

Operator Description Example
== Equal to 5 == 5 → true
~= Not equal to 5 ~= 3 → true
< Less than 3 < 5 → true
> Greater than 7 > 2 → true
<= Less than or equal 4 <= 4 → true
>= Greater than or equal 6 >= 6 → true

Relational Examples

local x = 10
local y = 20
local z = 10

print("x == z:", x == z)  -- true
print("x ~= y:", x ~= y)  -- true
print("x < y:", x < y)    -- true
print("y > x:", y > x)    -- true
print("x <= z:", x <= z)  -- true
print("y >= x:", y >= x)  -- true

-- String comparisons (lexicographic)
local str1 = "apple"
local str2 = "banana"
print("apple < banana:", str1 < str2)  -- true

-- Mixed type comparisons
print("10 == '10':", 10 == "10")       -- false (different types)
print("10 == tonumber('10'):", 10 == tonumber("10"))  -- true

Expected Output:

x == z:	true
x ~= y:	true
x < y:	true
y > x:	true
x <= z:	true
y >= x:	true
apple < banana:	true
10 == '10':	false
10 == tonumber('10'):	true

Logical Operators

Logical operators work with boolean values and support short-circuit evaluation:

Operator Description Returns
and Logical AND First falsy value or last value
or Logical OR First truthy value or last value
not Logical NOT Always returns boolean

Logical Examples

local a = true
local b = false
local c = nil
local d = "hello"
local e = 0

-- Basic logical operations
print("true and false:", a and b)      -- false
print("true or false:", a or b)        -- true
print("not true:", not a)              -- false
print("not false:", not b)             -- true

-- Short-circuit evaluation
print("nil and 'hello':", c and d)     -- nil (stops at first falsy)
print("'hello' and true:", d and a)    -- true (returns last value)
print("nil or 'hello':", c or d)       -- hello (returns first truthy)
print("false or nil:", b or c)         -- nil (returns last value)

-- Remember: only nil and false are falsy in Lua
print("0 and true:", e and a)          -- true (0 is truthy in Lua!)
print("'' and true:", "" and a)        -- true (empty string is truthy!)

-- Common pattern: default values
local name = nil
local default_name = name or "Anonymous"
print("Default name:", default_name)    -- Anonymous

Expected Output:

true and false:	false
true or false:	true
not true:	false
not false:	true
nil and 'hello':	nil
'hello' and true:	true
nil or 'hello':	hello
false or nil:	nil
0 and true:	true
'' and true:	true
Default name:	Anonymous

Miscellaneous Operators

String Concatenation (..)>

local first = "Hello"
local second = "World"
local greeting = first .. ", " .. second .. "!"
print("Concatenation:", greeting)

-- Automatic number to string conversion
local result = "The answer is " .. 42
print("Auto conversion:", result)

-- Multiple concatenations
local info = "Name: " .. "Alice" .. ", Age: " .. 25
print("Multiple concat:", info)

Expected Output:

Concatenation:	Hello, World!
Auto conversion:	The answer is 42
Multiple concat:	Name: Alice, Age: 25

Length Operator (#)

-- String length
local text = "Hello, Lua!"
print("String length:", #text)

-- Array length
local fruits = {"apple", "banana", "orange"}
print("Array length:", #fruits)

-- Empty containers
print("Empty string length:", #"")
print("Empty table length:", #{})

-- Table with gaps (use with caution)
local sparse = {1, 2, nil, 4}
print("Sparse array length:", #sparse)  -- May return 2 or 4, undefined!

Expected Output:

String length:	11
Array length:	3
Empty string length:	0
Empty table length:	0
Sparse array length:	2

Operator Precedence

Operators have different precedence levels. Here's the order from highest to lowest:

  1. ^ (exponentiation) - right associative
  2. not, #, - (unary)
  3. *, /, //, %
  4. +, - (binary)
  5. .. (concatenation) - right associative
  6. <, >, <=, >=, ~=, ==
  7. and
  8. or

Precedence Examples

-- Exponentiation is right associative
print("2 ^ 3 ^ 2:", 2 ^ 3 ^ 2)  -- 2 ^ (3 ^ 2) = 2 ^ 9 = 512

-- Multiplication before addition
print("2 + 3 * 4:", 2 + 3 * 4)  -- 2 + (3 * 4) = 14

-- Concatenation is right associative
print("'a' .. 'b' .. 'c':", "a" .. "b" .. "c")  -- "abc"

-- Comparison before logical
print("5 > 3 and 2 < 4:", 5 > 3 and 2 < 4)  -- (5 > 3) and (2 < 4) = true

-- Use parentheses to override precedence
print("(2 + 3) * 4:", (2 + 3) * 4)  -- 20
print("2 ^ (3 * 2):", 2 ^ (3 * 2))  -- 64

Expected Output:

2 ^ 3 ^ 2:	512
2 + 3 * 4:	14
'a' .. 'b' .. 'c':	abc
5 > 3 and 2 < 4:	true
(2 + 3) * 4:	20
2 ^ (3 * 2):	64

Practical Examples

Calculator Function

local function calculate(op, a, b)
    if op == "+" then
        return a + b
    elseif op == "-" then
        return a - b
    elseif op == "*" then
        return a * b
    elseif op == "/" then
        return b ~= 0 and a / b or "Division by zero!"
    elseif op == "%" then
        return b ~= 0 and a % b or "Division by zero!"
    elseif op == "^" then
        return a ^ b
    else
        return "Unknown operator"
    end
end

print("Calculator examples:")
print("10 + 5 =", calculate("+", 10, 5))
print("10 - 5 =", calculate("-", 10, 5))
print("10 * 5 =", calculate("*", 10, 5))
print("10 / 5 =", calculate("/", 10, 5))
print("10 % 3 =", calculate("%", 10, 3))
print("2 ^ 3 =", calculate("^", 2, 3))
print("10 / 0 =", calculate("/", 10, 0))

Range Checking

local function is_in_range(value, min, max)
    return value >= min and value <= max
end

local function get_grade(score)
    if is_in_range(score, 90, 100) then
        return "A"
    elseif is_in_range(score, 80, 89) then
        return "B"
    elseif is_in_range(score, 70, 79) then
        return "C"
    elseif is_in_range(score, 60, 69) then
        return "D"
    else
        return "F"
    end
end

print("Grade for 95:", get_grade(95))
print("Grade for 82:", get_grade(82))
print("Grade for 55:", get_grade(55))

Expected Output:

Calculator examples:
10 + 5 =	15
10 - 5 =	5
10 * 5 =	50
10 / 5 =	2
10 % 3 =	1
2 ^ 3 =	8
10 / 0 =	Division by zero!
Grade for 95:	A
Grade for 82:	B
Grade for 55:	F

Common Pitfalls

  • Division by zero: Check for zero before division to avoid errors
  • String vs number: Remember that "10" == 10 is false
  • Truthiness: Only nil and false are falsy; 0 and "" are truthy
  • Precedence: Use parentheses when in doubt about operator precedence
  • Short-circuit: and and or don't always return booleans

Checks for Understanding

  1. What's the difference between / and // operators?
  2. What does 10 and 20 return?
  3. How do you check if a number is between 10 and 20 (inclusive)?
  4. What's the precedence of the ^ operator?
  5. What does #"hello" return?
Show answers
  1. / performs regular division (returns float), // performs floor division (returns integer result)
  2. 20 - since 10 is truthy, and returns the second value
  3. number >= 10 and number <= 20
  4. Highest precedence and right associative
  5. 5 - the length of the string "hello"

Next Steps

Now that you understand all the operators in Lua, you're ready to explore string manipulation techniques and learn how to work with text data effectively.