You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? Keep it simple and clear!
I want to abbreviate numbers, simple
What is the issue? Include screenshots / videos if possible!
Previously, it would say i had 8.7k cash when i only had 8.69k cash, for issues related to my game i wanted it to return the floor, not round up. after trying to fix this ive ran into a new bug. its saying im trying to floor a nil value, when nothing should turn turn the number nil.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
i asked chatgpt but even chatgpt couldnt solve my problem.
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
this is a bindable function, the num argument is never nil
local function abbreviateNumber(number)
local abbreviations = {
{1e15, 'Q'},
{1e12, 'T'},
{1e9, 'B'},
{1e6, 'M'},
{1e3, 'K'},
}
for _, abbreviation in ipairs(abbreviations) do
local value, symbol = unpack(abbreviation)
if number >= value then
local abbreviatedNumber = number / value
return string.format('%.1f%s', abbreviatedNumber, symbol)
end
end
return tostring(number)
end
function script.Parent.abbreviate.OnInvoke(num)
local abbreviatedNumber = abbreviateNumber(num)
return math.floor(tonumber(abbreviatedNumber))
end
tonumber() returns nil in case it cannot convert the string.
The flooring would be better done before truncating anyway, because %.nf rounds decimals.
local abbreviations = {
{1e15, 'Q'},
{1e12, 'T'},
{1e9, 'B'},
{1e6, 'M'},
{1e3, 'K'},
}
local function abbreviateNumber(number)
for _, abbreviation in abbreviations do
local value, symbol = unpack(abbreviation)
if number >= value then
local abbreviatedNumber = math.floor((number / value) * 10) / 10
return string.format('%.1f%s', abbreviatedNumber, symbol)
end
end
return tostring(number)
end
local abbreviatedNumber = abbreviateNumber(8699)
print(abbreviatedNumber) --> 8.6K
(I reversed the table because that should make usual searches shorter.)
Update. Reversed the table back since Jess pointed out that the current code processing the table in ascending order would stop at the lowest adequate abbreviation value.
this worked, but i had to unreverse the abbreviations list. it returns the moment it finds one that fits, which may not be the biggest abbreviation possible. thank you for solving this though!
Unless I’m missing something, this is exactly why I reversed it. I imagine most numbers are going to revolve around thousands and millions, so it would make sense for K and M to be touched first in a linear search.
a bit late, but heres the explanation
with your method it would check K first, and since K fits, it would abbreviate it with k and then stop checking.
this is a problem because i could have 1.5m and it would return 1500k
checking biggest to smallest makes sure it abbreviates the best fit.
Ah, thanks for pointing it out, I overlooked the problem. In case someone else visits this thread and uses the code, I re-reversed the table Adapting the code to start at the lowest value really isn’t worth the performance gain (at all) compared to the readability and simplicity loss.
I guess the table could be iterated in reverse order, but it really doesn't matter.
local function abbreviateNumber(number)
for i=#abbreviations, 1, -1 do
local value, symbol = unpack(abbreviations[i])
if number >= value then
local abbreviatedNumber = math.floor((number / value) * 10) / 10
return string.format('%.1f%s', abbreviatedNumber, symbol)
end
end
return tostring(number)
end