# Most efficient way of converting a number in scientific notation into a Suffix and back?

I am trying to convert a number into a suffix as well as being able to unpack a suffix.
Example : 1 * 10^6 -> 1M
Example: 1B -> 10^9

The only knowledge I currently know is using if and elseif statements (which would be highly inefficient and unclean) to pack it into a suffix, but I have no clue on how I would be able to unpack a suffix.

Every post is Appreciated!

2 Likes

Maybe something like this?

``````local Suffixes = {"K", "M", "B", "T", "Q"}

local function GetSuffix(Input)
local Base, Exponent = string.match(Input, "(%d+)^(%d+)") -- get the seperate numbers
Base, Exponent = tonumber(Base), tonumber(Exponent)
if not Base or not Exponent then return end

local Index = math.floor(Number / 3) -- get the size of the number it is (hundred, thousand, million, etc.)
return (Base/10)..Suffixes[Index] -- return the result
end

print(GetSuffix("10^6")) -- 10M
``````

My code is untested btw lol

To do it the other way, you’d simply reverse the operations. i.e. Multiply base by 10, get the exponent

6 Likes

Updated Post: January 2nd, 2021

@VitalWinter made a pretty good suggestion, so I’ve rewritten the code to introduce this and made some additional improvements:

``````local suffixes = {"K", "M", "B", "T", "Q"} -- numbers don't go higher than 'Q' in Lua.

local function toSuffixString(n)
local i = math.floor(math.log(n, 1e3))
local v = math.pow(10, i * 3)
return ("%.1f"):format(n / v):gsub("%.?0+\$", "") .. (suffixes[i] or "")
end
``````

Then, if you want to convert back:

``````local function fromSuffixString(s)
local n, suffix = string.match(s, "(.*)(%a)\$")
if n and suffix then
local i = table.find(suffixes, suffix) or 0
end
end
``````

Original Post: September 12th, 2018

Personally I would do the following for converting a number to a string with a suffix.

``````local suffixes = {"K", "M", "B", "T", "Q", "Qu", "S", "Se", "O", "N", "D"}

local function toSuffixString(n)
for i = #suffixes, 1, -1 do
local v = math.pow(10, i * 3)
if n >= v then
return ("%.0f"):format(n / v) .. suffixes[i]
end
end
end
``````

While to do the reverse you could do something such as

``````local function fromSuffixString(s)
local v, suffix = s:match("(%d+)(.*)")
for i = 1, #suffixes do
if suffixes[i] == suffix then
end
end
end
``````
45 Likes

Thanks for the quick replies!

Oops clicked Send by accident way too early.

I’ve tested your code to see which one would help.

@woot3 yours seems to have worked but when I tried inputting 1500000 (1.5 Million), it came out as 2 million. I don’t want to be confusing players so decimals would be fine in this case.

1 Like

If you change the following line

``````return ("%.0f"):format(n / v) .. suffixes[i]
``````

to the following then you’ll be able to show numbers to 1 decimal place.

``````return ("%.1f"):format(n / v) .. suffixes[i]
``````

Generally I think it’s a good idea to round your numbers at some point to keep your strings short.

6 Likes

Also please make sure you do NOT do the converting from suffix form part (at least if you are trying to actually store or read data accurately). I am pretty sure you will not need it because of the rounding, but just as a precaution you do not want to have a constant 1.1B because you cannot round up fast enough before you leave.

2 Likes

Pretty sure I fixed it now, it was an issue with `string.match`. FYI you should learn to debug stuff like this yourself so we only have to show you what you need to do – that’s kind of what programming is about anyway (problem solving)

2 Likes

Instead of iterating through suffixes, you could check if a suffix exists at this index:

``````math.floor(math.log(n,1000))
``````
1 Like

How would I do that for a gui? This is the code I have in my gui:

``````script.Parent.Text = game.Players.LocalPlayer.leaderstats.Cash.Value

while true do

wait(0.1)

end
``````

Try something like

``````local suffixes = {"K", "M", "B", "T", "Q", "Qu", "S", "Se", "O", "N", "D"}

local function toSuffixString(n)
for i = #suffixes, 1, -1 do
local v = math.pow(10, i * 3)
if n >= v then
return ("%.0f"):format(n / v) .. suffixes[i]
end
end
end

``````

and also don’t use

because it can be optimised more with the code below that only runs whenever a change is made to the cash value

``````game.Players.LocalPlayer.leaderstats.Cash.Changed:Connect(function()
end)
``````
2 Likes

That’s pretty sensible. There are definitely some other things which could be improved so I’ll update the code.

``````local suffixes = {"K", "M", "B", "T", "Q"} -- numbers don't go higher than 'Q' in Lua.

local function toSuffixString(n)
local i = math.floor(math.log(n, 1e3))
local v = math.pow(10, i * 3)
return ("%.1f"):format(n / v):gsub("%.?0+\$", "") .. (suffixes[i] or "")
end
``````

This version rounds to one decimal place and removes trailing zeros after the decimal point which should result in better looking numbers.

Here’s the updated counterpart:

``````local function fromSuffixString(s)
local n, suffix = string.match(s, "(.*)(%a)\$")
if n and suffix then
local i = table.find(suffixes, suffix) or 0
end
end
``````
1 Like

Hey, I know this is an old topic, but I’m having a small issue.

``````toSuffixString(1157)
``````

would return “1.2K” instead of “1.1K”. Is there a way I can change this?

the usage of %.1f rounds the decimal automatically, in that case it went up

you can replace

``````("%.1f"):format(n / v)
``````

with

``````("%f"):format(math.floor(n / v * 10) / 10)
``````

this lets you do the rounding yourself, but only by rounding down

2 Likes