Module:NumberFormat2

-- Item suffixes. local suffixes={'k','M','G','T','P','E','Z','Y','B','aa','ab','ac', 'ad','ae','af','ag','ah','ai','aj','ak','al','am','an','ao','ap', 'aq','ar','as','at','au','av','aw','ax','ay','az','ba','bb','bc', 'bd','be','bf','bg','bh','bi','bj','bk','bl','bm','bn','bo','bp', 'bq','br','bs','bt','bu','bv','bw','bx','by','bz','ca','cb','cc', 'cd','ce','cf','cg','ch','ci','cj','ck','cl','cm','cn','co','cp', 'cq','cr','cs','ct','cu','cv','cw','cx','cy','cz','da','db','dc', 'dd','de','df','dg','dh','di','dj','dk','dl','dm','dn','do','dp', 'dq','dr','ds','dt','du','dv','dw','dx','dy','dz'} 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 if num:sub(#num, #num) == "E" or num:sub(#num, #num) == "e" then stop = stop - 1 end 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) 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 to go. 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