Formatting Numbers

lua-users home
wiki

The following implementation provides a function 'format_num' that allows one to format numbers as monetary values, e.g 12000000 as $12,000,000.00. This can be useful to format numeric values in reports.

Alternative code further down.

-- from sam_lie
-- Compatible with Lua 5.0 and 5.1.
-- Disclaimer : use at own risk especially for hedge fund reports :-)

---============================================================
-- add comma to separate thousands
-- 
function comma_value(amount)
  local formatted = amount
  while true do  
    formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
    if (k==0) then
      break
    end
  end
  return formatted
end

---============================================================
-- rounds a number to the nearest decimal places
--
function round(val, decimal)
  if (decimal) then
    return math.floor( (val * 10^decimal) + 0.5) / (10^decimal)
  else
    return math.floor(val+0.5)
  end
end

--===================================================================
-- given a numeric value formats output with comma to separate thousands
-- and rounded to given decimal places
--
--
function format_num(amount, decimal, prefix, neg_prefix)
  local str_amount,  formatted, famount, remain

  decimal = decimal or 2  -- default 2 decimal places
  neg_prefix = neg_prefix or "-" -- default negative sign

  famount = math.abs(round(amount,decimal))
  famount = math.floor(famount)

  remain = round(math.abs(amount) - famount, decimal)

        -- comma to separate the thousands
  formatted = comma_value(famount)

        -- attach the decimal portion
  if (decimal > 0) then
    remain = string.sub(tostring(remain),3)
    formatted = formatted .. "." .. remain ..
                string.rep("0", decimal - string.len(remain))
  end

        -- attach prefix string e.g '$' 
  formatted = (prefix or "") .. formatted 

        -- if value is negative then format accordingly
  if (amount<0) then
    if (neg_prefix=="()") then
      formatted = "("..formatted ..")"
    else
      formatted = neg_prefix .. formatted 
    end
  end

  return formatted
end

Example usage:

amount = 1333444.1
print(format_num(amount,2))
print(format_num(amount,-2,"US$"))

amount = -22333444.5634
print(format_num(amount,2,"$"))
print(format_num(amount,2,"$","()"))
print(format_num(amount,3,"$","NEG "))

Output:

1,333,444.10
US$1,333,400
-$22,333,444.56
($22,333,444.56)
NEG $22,333,444.563

RichardWarburton alternate version:

function comma_value(n) -- credit http://richard.warburton.it
	local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
	return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end

Example usage:

print(comma_value(9))
print(comma_value(999))
print(comma_value(1000))
print(comma_value('1333444.10'))
print(comma_value('US$1333400'))
print(comma_value('-$22333444.56'))
print(comma_value('($22333444.56)'))
print(comma_value('NEG $22333444.563'))

Output:

9
999
1,000
1,333,444.10
US$1,333,400
-$22,333,444.56
($22,333,444.56)
NEG $22,333,444.563

RecentChanges · preferences
edit · history
Last edited April 20, 2011 10:06 pm GMT (diff)