Sandbox Wiki
Advertisement

Documentation for this module may be created at Module:NumberFormat/doc

-- Item suffixes.
local suffixes={'K', 'M', 'B', 'T', 'Qa', 'Qi', 'Sx', 'Sp', 'Oc', 'No', 'Dc',
'Ud', 'Dd', 'Td', 'Qad', 'Qid', 'Sxd', 'Spd', 'Ocd', 'Nod', 'Vg',
'Uvg', 'Dvg', 'Tvg', 'Qavg', 'Qivg', 'Sxvg', 'Spvg', 'Ocvg', 'Novg',
'Tg', 'Utg', 'Dtg', 'Ttg', 'Qatg', 'Qitg', 'Sxtg', 'Sptg', 'Octg', 'Notg',
'Qag', 'Uqag', 'Dqag', 'Tqag', 'Qaqag', 'Qiqag', 'Sxqag', 'Spqag', 'Ocqag', 'Noqag',
'Qig', 'UQig', 'DQig', 'TQig', 'QaQig', 'QiQig', 'SxQig', 'SpQig', 'OcQig', 'NoQig',
'Sxg', 'USxg', 'DSxg', 'TSxg', 'QaSxg', 'QiSxg', 'SxSxg', 'SpSxg', 'OcSxg', 'NoSxg',
'Spg', 'USpg', 'DSpg', 'TSpg', 'QaSpg', 'QiSpg', 'SxSpg', 'SpSpg', 'OcSpg', 'NoSpg',
'Ocg', 'UOcg', 'DOcg', 'TOcg', 'QaOcg', 'QiOcg', 'SxOcg', 'SpOcg', 'OcOcg', 'NoOcg',
'Nog', 'UNog', 'DNog', 'TNog', 'QaNog', 'QiNog', 'SxNog', 'SpNog', 'OcNog', 'NoNog',
'C', 'Uc'}
 
local suffixesRev = {}
 
-- Set the #e__ bit.
for i = 1, #suffixes do
  suffixesRev[suffixes[i]:lower()] = ((i + 1) * 3) - 3
end
 
-- Set the original number-and-letter bit.
function expToShort(exp)
  return suffixes[math.floor(exp / 3)]
end
 
function shortToExp(short)
  return suffixesRev[short:lower()]
end
 
function decompNum(num)
  local base, mant, suffix, start, stop
  local exp = 0
 
  -- Strip whitespace.
  num = num:gsub('%s', '')
 
  --lua stop, no, go home lua you're drunk, that's not a regex
  start, stop = num:find('%d[%d,]*%.?%d*[eE]?%d*')
  if (start ~= nil) then base = num:sub(start, stop)
  else return end
 
  start, stop = num:find('%a+$', stop + 1)
  if (start ~= nil) then suffix = num:sub(start, stop) end
 
  start, stop = base:find('^%d[%d,]*%.?%d*')
  if (start ~= nil) then mant = base:sub(start, stop)
  else return end
 
  -- Remove all commas.
  mant = mant:gsub(',', '')
 
  start, stop = base:find('[eE]%d*$')
  if (start ~= nil) then 
    exp = base:sub(start + 1, stop)  -- xms
    exp = tonumber(exp)
  end
  if (suffix ~= nil) then exp = exp + shortToExp(suffix) end
 
  return mant, exp
end
 
function normalize(mant, exp)
  mant = mant:gsub('^0+', '')
  mant = mant:gsub('%.$', '')
  local dot = mant:find('%.') or #mant + 1
  mant = mant:gsub('[0.]+$', '')
  if (mant == '') then return '0', 0 end
  exp = exp + (dot - 2)
  mant = mant:gsub('%.', '')
 
  return mant, exp
end
 
function sciSig(mant, sig)
  if (#mant == 1) then return mant end
  return mant:sub(1, 1) .. '.' .. mant:sub(2, sig)
end
 
function intSig(mant, sig)
  local res
  if (#mant >= sig) then res = mant:sub(1, sig)
  else res = mant .. string.rep('0', sig - #mant) end
  if (#res <= 3) then return res
  else
    local out = res:sub(-3)
    res = res:sub(1, -4)
    while (#res > 0) do
      out = res:sub(-3) .. ',' .. out
      res = res:sub(1, -4)
    end
    return out
  end
end
 
function otherSig(mant, base, exp, sig)
  mant = mant:sub(1, sig)
  local res = intSig(mant, exp % base + 1)
  if (#mant <= base) then return res end
  return res .. '.' .. mant:sub(exp % base + 2)
end
 
function sci(mant, exp)
  return sciSig(mant, 4) .. '<sub>E</sub>' .. exp
end
 
function eng(mant, exp)
  return otherSig(mant, 3, exp, 4) .. '<sub>E</sub>' .. (exp - exp % 3)
end
 
function int(mant, exp)
  return intSig(mant, exp + 1)
end

function short(mant, exp)
  return otherSig(mant, 1, exp, 4) .. '&nbsp;' .. expToShort(exp) --,3
end

function Scientific(frame)
  mant, exp = normalize(decompNum(frame.args[1]))
  if (exp >= 0 and exp < 6) then return ShortScale(frame)
  else return sci(mant, exp) end
end

function Engineering(frame)
  mant, exp = normalize(decompNum(frame.args[1]))
  if (exp >= 0 and exp < 6) then return ShortScale(frame)
  elseif (exp < 0) then return Scientific(frame)
  else return eng(mant, exp) end
end
 
function ShortScale(frame)
  mant, exp = normalize(decompNum(frame.args[1]))
  if (exp < 0) then return Scientific(frame)
  elseif (exp < 3) then return otherSig(mant, 3, exp, 4)
  elseif (exp < 6) then return int(mant, exp)
  else return short(mant, exp) end
end

function TableCell(frame)
  short = ShortScale(frame)
  sci = Scientific(frame)
  if (short == sci) then
    return short
  else
    return short .. '<br/>' .. sci
  end
end
 
-- Return the text that's gonna go where it needs togo.
function Inline(frame)
  short = ShortScale(frame)
  sci = Scientific(frame)
  if (short == sci) then
    return short
  else
    return short .. ' (' .. sci .. ')'
  end
end
 
function Debug(frame)
  local res = ''
  for k,v in pairs(frame.args) do
    mant, exp = normalize(decompNum(v))
    res = res .. '<b>' .. k .. '</b>: ' .. v .. '(' .. type(v) .. ', '
    res = res .. mant .. ', ' .. exp .. ')<br/>'
  end
  return res
end
 
local package = {}
 
package.Scientific = Scientific
package.Engineering = Engineering
package.ShortScale = ShortScale
package.TableCell = TableCell
package.Inline = Inline
package.Debug = Debug
 
return package
Advertisement