Arithmetic and Relational Operators
Use +, -, *, /, //, %, ^ and comparison operators effectively.
Arithmetic and Relational Operators is a free Lua Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Arithmetic Operators Overview
Lua provides a full set of arithmetic operators: + (add), - (subtract), * (multiply), / (float divide), // (floor divide), % (modulo), ^ (exponentiation), and unary - (negation). Understanding when each returns an integer vs float is crucial in Lua 5.3+.
print(10 + 3) -- 13
print(10 - 3) -- 7
print(10 * 3) -- 30
print(10 / 3) -- 3.3333... (always float)
print(10 // 3) -- 3 (floor division)
print(10 % 3) -- 1 (modulo)
print(2 ^ 10) -- 1024.0 (always float)
print(-5) -- -5Integer vs Float Division
The / operator always returns a float, even when dividing two integers that divide evenly. The // floor division operator returns an integer only when both operands are integers; if either is a float, the result is a float but still rounded down.
The ^ exponentiation operator always converts to float, so 2^3 gives 8.0, not 8. Use math.tointeger() to convert back if needed.
print(6 / 2) -- 3.0 (float!)
print(6 // 2) -- 3 (integer)
print(6.0 // 2) -- 3.0 (float floor)
print(7 // 2) -- 3 (floor toward -inf)
print(-7 // 2) -- -4 (floor, not truncate!)
print(2 ^ 3) -- 8.0 (always float)Modulo Operator
Lua's % operator is defined as a % b == a - floor(a/b) * b. This means it follows the sign of the divisor, not the dividend. This differs from C/Java where the result follows the dividend sign.
The modulo operator is useful for wrapping values, cycling through arrays, and implementing ring buffers. A common use: i % n cycles through 0 to n-1.
print(10 % 3) -- 1 (positive)
print(-10 % 3) -- 2 (sign of divisor!)
print(10 % -3) -- -2 (sign of divisor)
-- Cycling 1..5 example
for i = 1, 8 do
local idx = (i - 1) % 5 + 1
io.write(idx .. " ") -- 1 2 3 4 5 1 2 3
endRelational Operators
Lua's relational operators return booleans: == (equal), ~= (not equal), <, >, <=, >=. Note that Lua uses ~= for inequality, unlike != in most languages.
Comparing values of different types with == always returns false — there's no implicit coercion for equality checks. 1 == "1" is false in Lua.
print(3 == 3) -- true
print(3 ~= 4) -- true
print(3 < 4) -- true
print(3 >= 3) -- true
-- No cross-type equality coercion
print(1 == "1") -- false
print(0 == false) -- false
-- Strings compare lexicographically
print("abc" < "abd") -- trueLogical Operators: and, or, not
Lua's logical operators are and, or, and not. Unlike many languages, and and or do not return booleans — they return one of their operands. This enables idiomatic patterns like default values and conditional assignment.
a and breturnsaifais falsy, otherwise returnsba or breturnsaifais truthy, otherwise returnsb
-- and/or return operands, not booleans
print(1 and 2) -- 2
print(false and 2) -- false
print(1 or 2) -- 1
print(false or 2) -- 2
-- Default value idiom
local name = nil
local display = name or "Anonymous"
print(display) -- AnonymousThe Ternary Idiom
Lua has no ternary operator (?:), but you can emulate one using and/or. The pattern condition and value_if_true or value_if_false works as long as value_if_true is not nil or false.
This is a very common Lua idiom. Be aware of the edge case: if the true branch is literally false, the pattern fails — use an if statement instead.
local x = 10
-- Ternary idiom
local label = x > 5 and "big" or "small"
print(label) -- big
-- Works for non-false truthy values
local age = 20
local status = age >= 18 and "adult" or "minor"
print(status) -- adult
-- Edge case: true branch is false -> use if
local val = true and false or "fallback"
print(val) -- fallback (wrong!)Operator Precedence
Lua operator precedence from lowest to highest: or, and, comparisons (< > <= >= == ~=), |, ~, &, shifts, .., + -, * / // %, unary (not # - ~), ^. The ^ and .. operators are right-associative; all others are left-associative.
-- Precedence examples
print(2 + 3 * 4) -- 14 (not 20)
print(2 ^ 3 ^ 2) -- 512 (right assoc: 2^(3^2) = 2^9)
print(not 1 == 1) -- false (not (1) == 1 => false == 1)
print(not (1 == 1)) -- false
-- Use parens to be explicit
print((2 + 3) * 4) -- 20Bitwise Operators (Lua 5.3+)
Lua 5.3 added native bitwise operators that work on integers: & (AND), | (OR), ~ (XOR when binary, NOT when unary), << (left shift), >> (right shift). These are not available in Lua 5.1/5.2 without a library.
Bitwise operators require integer operands. Passing a float causes a runtime error unless the float has an exact integer value.
-- Bitwise operators (Lua 5.3+)
print(0xFF & 0x0F) -- 15 (AND)
print(0xF0 | 0x0F) -- 255 (OR)
print(0xFF ~ 0x0F) -- 240 (XOR)
print(~0) -- -1 (bitwise NOT)
print(1 << 4) -- 16 (left shift)
print(256 >> 4) -- 16 (right shift)String Length and Concatenation
The # operator returns the length of a string in bytes, and the .. operator concatenates two strings. When you apply .. to numbers, Lua automatically converts them to strings. However, mixing types with + follows coercion rules — a string that looks like a number can be used in arithmetic.
local s = "hello"
print(#s) -- 5
print(s .. " world") -- hello world
print(1 .. 2) -- 12 (number to string)
-- Length of table = array part length
local t = {10, 20, 30}
print(#t) -- 3
-- Beware: # on tables with holes is undefined
local h = {1, nil, 3}
print(#h) -- 1 or 3 (undefined behavior!)Common Mistakes with Operators
Several operator-related bugs are common in Lua: forgetting that / always returns float; using != instead of ~= (syntax error); expecting 0 or "" to be falsy (they're truthy); and relying on and/or when the true branch might be false.
Always test boundary conditions, especially around floor division with negative numbers where // floors toward negative infinity.
-- Common mistakes
-- 1. / is always float
local result = 10 / 2
print(math.type(result)) -- float, not integer!
-- 2. ~= not !=
-- if x != 5 then -- SYNTAX ERROR!
if 3 ~= 5 then print("not equal") end
-- 3. 0 is truthy
if 0 then print("0 is truthy in Lua!") end
-- 4. Negative floor division
print(-7 // 2) -- -4 (not -3!)Quick Check
What is the result of -7 // 2 in Lua?
Recap: Arithmetic and Relational Operators
Key points covered:
/always returns float;//floors toward negative infinity^always returns float and is right-associative~=is the not-equal operator (not!=)and/orreturn operands, not booleans — enables default value idiom- Only
nilandfalseare falsy —0and""are truthy - Bitwise operators (
& | ~ << >>) require Lua 5.3+ integers
Next: type coercion and explicit conversion functions.
Frequently asked questions
Is the “Arithmetic and Relational Operators” lesson free?
Yes — the full text of “Arithmetic and Relational Operators” is free to read here on the web, and the Lua Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Lua Academy course, upgrade to CoddyKit PRO.
What will I learn in “Arithmetic and Relational Operators”?
Use +, -, *, /, //, %, ^ and comparison operators effectively. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Lua Academy?
No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Arithmetic and Relational Operators” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Lua Academy lesson?
Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Lua Data Types Overview
- Declaring Variables in Lua
- Arithmetic and Relational Operators
- Type Coercion and Conversion