Page 1 of 1

Formatting a number [solved]

Posted: Sat Oct 26, 2019 7:03 am
by Crossing
So i've been trying to figure out how to format a number.

i know how to do it in the following way: (using

1000000 = 1,000,000

However, I want it to be this way:

1000000 = 1m
1200000 = 1.2m
500000 = 500k

The article doesn't really go over how i would accomplish this? I'm assuming you could just count the 0's and put the corresponding letter with amount of numbers to be shown. (500k, 1m, 1.2m)

I feel like this wouldn't be really efficient?

Re: Formatting a number

Posted: Sat Oct 26, 2019 8:54 am
by raidho36
That's pretty much how you do it. The alternative way is to divide the number by 1000 and increment the suffix if it's still bigger than 1000.

Re: Formatting a number

Posted: Sat Oct 26, 2019 9:19 am
by zorg
Although, "counting the zeros" can be done many ways; if you'd plan on always converting to strings then doing some pattern matching, that's wasteful and slow; math has you covered though, you just need the 10-based logarithm of a number to know how many digits it has; after that, you could treat small numbers (below some cutoff like 1000) without a suffix, then between that and 1000000 with the "k" suffix, then finally above that with the "M" suffix. You probably also want to cut the non-significant digits to some amount, say 3 digits for all magnitudes.

Code: Select all

local suffix = {[0]='','','','k','k','k','M','M','M'} -- could be continued, or M replaced by mil if you prefer...
function dynamicFormat(x)
  local magnitude = math.max(0, math.floor(math.log10(x))) -- no suffixes for values between 0 and 1, though that could also be implemented...
  return string.format("%0.3f%s", x/magnitude, suffix[magnitude])
Something like that i guess.

Re: Formatting a number

Posted: Sat Oct 26, 2019 10:13 am
by pgimeno
Well, it depends on how you want to deal with numbers like 12345678. Counting the zeros will not work in this case.

My version is similar to zorg's but uses 'g' for formatting instead of 'f', which automatically removes trailing zeros. Also, it divides by the correct number ;)

Code: Select all

local format
  local letters = {'', 'k', 'm', 'b', 't', 'qd', 'qt'}
  function format(number)
    local log = math.max(math.log10(number), 0)
    local pwr = math.floor(log / 3)
    assert(pwr + 1 <= #letters, "Number too big - we don't have enough suffixes")
    return ("%.3g%s"):format(number / 1000^pwr, letters[pwr + 1])

print(format(0)) -- 0
print(format(1)) -- 1
print(format(123)) -- 123
print(format(999)) -- 999
print(format(1000)) -- 1k
print(format(1234)) -- 1.23k
print(format(2345)) -- 2.35k, note it rounds
print(format(23456)) -- 23.5k
print(format(234567)) -- 235k
print(format(2345678)) -- 2.35m
print(format(23456789)) -- 23.5m
print(format(2345678901)) -- 2.35b
print(format(2345678901234)) -- 2.35t
print(format(234567890123456789)) -- 235qd
print(format(234567890123456789012)) -- 235qt
print(format(2345678901234567890123)) -- abort, "Number too big, we don't have enough suffixes"
(Edited to rename "letters" to "suffixes" and to extend the suffixes by replacing "q" with "qd" and adding "qt"; also to make the suffix check dynamic)