BWayne
BWayne

Reputation: 171

WoW - rounding to two decimal places in Lua

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?

Upvotes: 10

Views: 27823

Answers (3)

George Williams
George Williams

Reputation: 31

Here is a flexible function to round to different number of places. I tested it with negative numbers, big numbers, small numbers, and all manner of edge cases, and it is useful and reliable:

function Round(num, dp)
    --[[
    round a number to so-many decimal of places, which can be negative, 
    e.g. -1 places rounds to 10's,  
    
    examples
        173.2562 rounded to 0 dps is 173.0
        173.2562 rounded to 2 dps is 173.26
        173.2562 rounded to -1 dps is 170.0
    ]]--
    local mult = 10^(dp or 0)
    return math.floor(num * mult + 0.5)/mult
end

Upvotes: 2

DarkWiiPlayer
DarkWiiPlayer

Reputation: 7056

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.

Upvotes: 14

Nathanyel
Nathanyel

Reputation: 424

There's already a good answer, but I'm unsure why you extract the mantissa at all, simply perform what you do with the mantissa on the whole number: multiply by 100, round (or floor) normally, then divide by 100.

If it helps, you can also view and write this as: divide by 0.01 (the precision you want to have) then round, then multiply by 0.01 again.

Lua doesn't have round, but to employ floor as a round function, simply use floor( x + 0.5 )
Although with percentages of levels, you might prefer a floor anyway, since displaying 0.995 as 100% would be misleading.

Upvotes: 0

Related Questions