Skip to content
Lesson 3 of 18

Step 1 of 5 · Reading · ~4 min

Learn

First Steps

Numbers and Arithmetic

Lua has a single number type with two internal subtypes: integer and float, both 64-bit. You almost never declare which one you want — the operator decides — but you do need to know which one you ended up with, because it changes what gets printed.

Which operator gives which subtype?

ExpressionSubtypePrints as
7 + 2integer9
7 - 2integer5
7 * 2integer14
7 % 2integer1
7 // 2integer3
7 / 2float3.5
6 / 2float3.0
2 ^ 10float1024.0

Read the last two rows twice. / always produces a float, even when the division comes out even, and ^ always produces a float. 6 / 2 prints 3.0, not 3. On a byte-exact test, those two characters are the whole difference between accepted and rejected.

print(6 / 2)
print(6 // 2)
print(2 ^ 3)
print(7 % 3)

--> 3.0
--> 3
--> 8.0
--> 1

How do I keep an integer?

// is floor division: divide, then round down. Given two integers it gives back an integer.

print(7 // 2)
print(-7 // 2)
print(math.floor(3.7))
print(math.floor(-3.7))

--> 3
--> -4
--> 3
--> -4

Rounding is toward negative infinity, not toward zero — -7 // 2 is -4, not -3. % is defined to match, so the remainder always carries the sign of the divisor and -7 % 2 is 1. That makes n % 2 == 1 a reliable odd-number test even for negatives, which it is not in C or Java, where -7 % 2 comes out as -1.

The math library

print(math.max(3, 9, 4))
print(math.min(3, 9, 4))
print(math.abs(-5))
print(math.floor(2.5))
print(math.ceil(2.1))
print(math.sqrt(16))

--> 9
--> 3
--> 5
--> 2
--> 3
--> 4.0

math.sqrt is the trap in that list: like /, it always hands back a float, so a perfect square still prints with a .0.

Turning text into numbers

Everything io.read() gives you is a string. tonumber converts it.

print(tonumber("42") + 1)
print(tonumber("3.5"))
print(tonumber("twelve"))

--> 43
--> 3.5
--> nil

tonumber returns nil — not zero, not an error — when the text is not a number. That nil then travels one more line and detonates there instead:

✗ blank or non-numeric input

local n = tonumber(io.read())
print(n * 2)

--> script.lua:2: attempt to perform arithmetic on a nil value (local 'n')

Read the parenthetical first whenever a run blows up. Lua tells you the file, the line, and which value was nil — here it names n directly, which is far more than most languages give you.

Conversion follows the way Lua reads literals, so tonumber("42") is an integer while tonumber("42.0") is a float. Same digits on stdin, different characters on stdout.

Why doesn't 0.1 + 0.2 equal 0.3?

Floats are IEEE 754 doubles, and most decimal fractions have no exact binary form. Lua prints numbers to fourteen significant digits, which politely hides the error — but comparison does not.

print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
print(math.abs((0.1 + 0.2) - 0.3) < 1e-9)

--> 0.3
--> false
--> true

✓ compare floats with a tolerance · ✗ compare floats with ==

One more rule worth memorising: equality never converts between strings and numbers, but arithmetic does — and that conversion always lands you in a float.

print("10" == 10)
print("10" + 1)

--> false
--> 11.0

That .0 is the sting. Skipping tonumber feels harmless because the arithmetic still works, but "3" * "4" is 12.0, never 12. The string route is a one-way trip into floats.

Your exercise

Rectangle Area reads a width and a height, one per line, and prints their product.

The starter already calls tonumber(io.read()) for both, so all you add is the printing.

The mistake the grader will catch is a stray float. The tests expect 12, 100 and 0 — plain integers, no decimal point. Multiplying with * keeps you in integers; the moment you route the calculation through /, ^ or math.sqrt, Lua hands back a float and 12 arrives as 12.0, failing every test. Deleting the starter's tonumber calls gets you there by a different road: "3" * "4" coerces through the string path and also prints 12.0. Finally, resist special-casing a zero side — the hidden test uses a height of 0 and wants exactly 0.

Up nextString BasicsStrings

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…