13. Numbers and math

Lua numbers come in two flavours, do the usual arithmetic, and plug into a small library of helpers. This chapter covers what you need for game logic: rounding, random numbers, basic maths.

Integers and floats

Lua has two kinds of number:

  • Integer. A whole number with no decimal part: 0, 7, -42.
  • Float. A number with a decimal point: 3.14, 0.5, -1.0.

Most of the time you do not have to care which is which. 7 is an integer, 7.0 is a float, and Lua mixes them freely. Two integers produce an integer; anything with a float produces a float.

type() reports both as "number". To tell them apart, use math.type():

print(math.type(7))     -- integer
print(math.type(7.0))   -- float
print(math.type(3.14))  -- float

Arithmetic

The familiar operators are all here, plus two less common in everyday maths:

Operator Name Example Result
+ addition 3 + 2 5
- subtraction 7 - 4 3
* multiplication 6 * 7 42
/ float division 7 / 2 3.5
// integer division 7 // 2 3
% modulo (remainder) 7 % 3 1
^ power 2 ^ 8 256.0

Three are worth a closer look:

Float division / always gives a float, even when the answer is whole. 6 / 3 is 2.0, not 2.

Integer division // drops everything after the decimal point. 7 // 2 is 3. -7 // 2 is -4, because it rounds toward negative infinity, not toward zero.

Modulo % is the remainder after integer division. 7 % 3 is 1 because 7 = 2 * 3 + 1. It is the standard way to ask "is this number even?" — n % 2 is 0 for evens and 1 for odds.

print(7 / 2)    -- 3.5
print(7 // 2)   -- 3
print(7 % 2)    -- 1
print(2 ^ 8)    -- 256.0

Open exercises/13/01-arithmetic.lua. Predict each printed result before running, then run and check.

The math library

Lua's math library has the helpers you reach for most:

Function What it does
math.floor(x) Largest integer not greater than x. floor(3.7) -> 3.
math.ceil(x) Smallest integer not less than x. ceil(3.2) -> 4.
math.abs(x) The absolute value. abs(-5) -> 5.
math.sqrt(x) Square root.
math.min(a, b) The smaller of two numbers.
math.max(a, b) The larger of two numbers.
math.pi The constant 3.1415... (a value, not a function).

Call them like any other function:

print(math.floor(3.7))    -- 3
print(math.ceil(3.2))     -- 4
print(math.sqrt(16))      -- 4.0
print(math.min(7, 3))     -- 3
print(math.pi)            -- 3.1415926535898

Random numbers

math.random picks a random number. It has three forms:

  • math.random() returns a float between 0.0 and 1.0.
  • math.random(n) returns a whole number from 1 to n (both ends included). math.random(6) is a six-sided die.
  • math.random(a, b) returns a whole number from a to b, both ends included. math.random(1, 100) gives 1 through 100.
print(math.random())        -- e.g. 0.6238...
print(math.random(6))       -- e.g. 4
print(math.random(1, 100))  -- e.g. 73

Lua 5.4 reseeds its random number generator every time the interpreter starts, so you do not have to call math.randomseed yourself. Older Lua versions (and some embedded ones) needed seeding before random numbers were actually random.

Turning text into a number

When a value arrives as a string but you need to do maths with it, use tonumber:

local text = "42"
local n = tonumber(text)
print(n + 1)            -- 43

If the text cannot become a number, tonumber returns nil:

print(tonumber("hello"))  -- nil

You will use tonumber a lot in the next chapter, where the program reads keyboard input. Whatever the user types arrives as a string, even if they typed digits.

Homework

Problem 1 — Rectangle area

Open exercises/13/homework/01-rectangle-area.lua. Two variables hold a rectangle's width and height. Compute the area and print it with a label, for example Area: 24.

Problem 2 — Floor and ceil

Open exercises/13/homework/02-floor-and-ceil.lua. A variable holds the float 3.7. Print it as-is, after math.floor, and after math.ceil. Add one comment line explaining the difference between floor and ceil.

Problem 3 — Roll two dice

Open exercises/13/homework/03-roll-two-dice.lua. "Roll" two six-sided dice and print the results like this:

Die 1: 4
Die 2: 6
Total: 10

Use math.random for the rolls. Roll each die separately so the two values are independent.

Challenge — Hypotenuse

Open exercises/13/homework/04-hypotenuse.lua. Two variables hold the two short sides of a right triangle (a and b). Compute and print the hypotenuse c using the Pythagorean theorem:

c = sqrt(a^2 + b^2)

Print all three values labelled. Round the hypotenuse to two decimal places with string.format and the %.2f placeholder from chapter 12.

Stuck or finished? Open the homework solutions page.