Formatting Numbers

With .., you can build any line, but numbers don't always come out the way you want. A price of 2.5 coins is printed as 2.5, not 2.50, and a division that works out prints 5.0. The function string.format gives you control. You give it a template, a text with placeholders called format specifiers, and the values to put into them:

local crop = "pumpkins"
local count = 3
local price = 2.5
print(string.format("%d %s for %.2f coins", count, crop, price))

This prints:

3 pumpkins for 2.50 coins

Each format specifier starts with %:

  • %d is a whole number,
  • %.2f is a decimal number with 2 decimal places, rounded (%.1f gives one),
  • %s is any value as text: a string, a number, true, nil…,
  • %% is a percent sign.

The values fill the format specifiers in order: the first value goes into the first one, the second into the second, and so on.

string.format doesn't print anything itself. It returns the finished text, which you print or store in a variable:

local total = 10 / 4
local line = string.format("Total: %.2f coins", total)
print(line)
print(string.format("%d eggs", 10 / 2))
print(string.format("%d%% sold", 75))

This prints:

Total: 2.50 coins
5 eggs
75% sold

%d printed 5.0 as 5: it accepts a float, as long as it's whole. If it isn't, Lua reports an error:

print(string.format("%d coins", 3.5))

Lua reports:

main.lua:1: bad argument #2 to 'format' (number has no integer representation)

Bad argument #2 means that the second value you gave to format is wrong (the template is the first one). Number has no integer representation: 3.5 can't be written as a whole number. Use %.2f, or round the number first, for example with math.floor.

When a value is missing, you get a similar error: string.format("%s and %s", "Emma") ends with bad argument #3 to 'format' (no value), because there's no third value.

Instructions

Run the program. The first line is printed, but the second one ends with an error: total is 13.5, and %d only takes whole numbers. Change the format specifier so that the total is printed with two decimal places:

3 boxes of strawberries
Total: 13.50 coins

Hugo the trader pays only in whole coins, and he rounds down. On the next line, print what he pays: use %d and math.floor:

3 boxes of strawberries
Total: 13.50 coins
Hugo pays: 13 coins

Finally, print one line for Emma's notebook with one string.format: %s for the item, %d for the boxes, and %.2f for the box price and for the total:

3 boxes of strawberries
Total: 13.50 coins
Hugo pays: 13 coins
strawberries: 3 x 4.50 = 13.50

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

9/10