Module:NumberFormat

-- 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) .. 'E' .. exp end function eng(mant, exp) return otherSig(mant, 3, exp, 4) .. 'E' .. (exp - exp % 3) end function int(mant, exp) return intSig(mant, exp + 1) end

function short(mant, exp) return otherSig(mant, 1, exp, 4) .. ' ' .. 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 .. ' ' .. 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 .. ' .. k .. : ' .. v .. '(' .. type(v) .. ', '   res = res .. mant .. ', ' .. exp .. ') ' 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