Difference between revisions of "Module:BaseConvert"
Jump to navigation
Jump to search
blackwiki>Toohool (add support for input bases other than 10) |
blackwiki>Toohool (fix handling of string input) |
||
| Line 21: | Line 21: | ||
-- strip off any leading '0x' (unless x is a valid digit in the input base) | -- strip off any leading '0x' (unless x is a valid digit in the input base) | ||
| + | from = tonumber(from) | ||
if not from or from < 34 then | if not from or from < 34 then | ||
local c | local c | ||
| Line 34: | Line 35: | ||
if c > 0 then sign = '-' end | if c > 0 then sign = '-' end | ||
| − | from = | + | from = from or 10 |
local num = tonumber(n, from) | local num = tonumber(n, from) | ||
base = tonumber(base) | base = tonumber(base) | ||
Revision as of 04:16, 24 February 2013
Converts numbers to a specified base between 2 and 36, for use in templates such as {{binary}}, {{octal}}, {{hexadecimal}}, etc.
Example usage:
local BaseConvert = require('Module:BaseConvert')
BaseConvert.convert({n = 14600926, base = 16}) -- returns 'DECADE'
Arguments:
- n - (required) the number to be converted, as a string. It may be a number instead, if the input base is 10.
- base - (required) the base to which the number should be converted. May be between 2 and 36, inclusive.
- from - the base of the input. Defaults to 10 (or 16 if the input has a leading '0x'). Note that bases other than 10 are not supported if the input has a fractional part.
- precision - number of digits to be rendered after the radix point. Trailing zeros will be added if needed. If not specified, however many digits are needed will be shown, up to 10.
- width - minimum number of digits to be rendered before the radix point. Leading zeros will be added if needed.
- default - Value to return if n is empty or non-numeric. Defaults to the value of n.
- prefix / suffix - wikitext to add before/after the returned result. Will not be added if n is empty or non-numeric. For example, you might use a prefix of
0xwhen converting to hex, or a suffix of<sub>8</sub>when converting to octal.
--
-- Converts numbers to a specified base between 2 and 36, for use in
-- templates such as {{binary}}, {{octal}}, {{hexadecimal}}, etc.
--
-- from - the base of the input. Defaults to 10 (or 16 if the input has a
-- leading '0x'). Note that bases other than 10 are not supported if the
-- input has a fractional part.
-- precision - number of digits to be rendered after the radix point. Trailing
-- zeros will be added if needed. If not specified, however many digits are
-- needed will be shown, up to 10.
-- width - minimum number of digits to be rendered before the radix point.
-- Leading zeros will be added if needed.
--
local p = {}
local digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
function p._convert(n, base, from, precision, width)
n = '' .. n -- convert to a string
-- strip off any leading '0x' (unless x is a valid digit in the input base)
from = tonumber(from)
if not from or from < 34 then
local c
n, c = n:gsub('^(-?)0[Xx]', '%1')
if c > 0 and not from then from = 16 end
end
-- check for a negative sign. Do this while the input is still in string form,
-- because tonumber doesn't support negative numbers in non-10 bases.
local sign = ''
local c
n, c = n:gsub('^-', '')
if c > 0 then sign = '-' end
from = from or 10
local num = tonumber(n, from)
base = tonumber(base)
precision = tonumber(precision)
width = tonumber(width)
if not num or not base then return n end
local i, f = math.modf(num)
local t = {}
repeat
local d = (i % base) + 1
i = math.floor(i / base)
table.insert(t, 1, digits:sub(d, d))
until i == 0
while #t < (width or 0) do
table.insert(t, 1, '0')
end
local intPart = table.concat(t, '')
-- compute the fractional part
local tf = {}
while f > 0 and #tf < (precision or 10) do
f = f * base
i, f = math.modf(f)
table.insert(tf, digits:sub(i + 1, i + 1))
end
-- add trailing zeros if needed
if precision and #tf < precision then
for i = 1, precision - #tf do
table.insert(tf, '0')
end
end
fracPart = table.concat(tf, '')
-- remove trailing zeros if not needed
if not precision then
fracPart = fracPart:gsub('0*$', '')
end
-- add the radix point if needed
if #fracPart > 0 then
fracPart = '.' .. fracPart
end
return sign .. intPart .. fracPart
end
function p.convert(frame)
local n = frame.args.n
local base = frame.args.base
local from = frame.args.from
local precision = frame.args.precision
local width = frame.args.width
return p._convert(n, base, from, precision, width)
end
return p