WoW - rounding to two decimal places in Lua

BWayne picture BWayne · Sep 16, 2019 · Viewed 7.1k times · Source

I'm trying to display my total experience points as a percentage rounded to two decimals. I have come up with a solution, but its quite clunky. There has to be a better way.

Here is what I have:

local xpPercentage = (((UnitXP("player") / UnitXPMax("player"))*100))
-- 63.4587392473
local xpMantissa = xpPercentage - floor(xpPercentage)
-- .4587392473
local xpTwoDec = (floor(xpMantissa * 100)/100) + floor(xpPercentage)
-- 63.45

Again, this does what I want, but is there a prettier way to do it?

Answer

DarkWiiPlayer picture DarkWiiPlayer · Sep 16, 2019
local formatted = string.format(
   "%.2f %%",
   UnitXP('player') / UnitXPMax('player') * 100
)

That's the standard Lua way to do it, which should work for you as well. Unless WoW has removed that function, which would be silly.

Note that type(formatted) is String, not a number.


string.format, as described in the manual, takes a format string as its first argument, followed by a series of values you want to splice into the format string.

The format string will mostly be treated literally, except special tokens that start with %. The number of additional arguments should be equal to the number of these tokens in the format string.

In the example above, %f means "insert a float here"; for example, string.format("hello %f world", 5.1") would return "hello 5.1 world". Adding stuff after the % and before the f you can tell it how exactly to format it.

Here's an example using all the options: string.format("%x6.2f", 2.264)

From left to right:

  • % marks the start
  • x tells it to pad right with xs
  • 6 tells it the whole thing should be 5 characters long
  • .2 tells it to round (or pad with 0s) to 2 decimal places

So, the result would be xx2.26

Finally, since % holds special meaning in the format string, if you want a literal % you have to write %% instead.

"%.2f %%" thus means:

A float, rounded or padded to 2 decimals, followed by a space and a percent sign. The second argument to format must then be a number, or the function will error.