Module:BaseConvert/sandbox
Appearance
From Wikipedia, the free encyclopedia
Warning This Lua module is used on approximately 37,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them.
Converts numbers to a specified base between 2 and 36, for use in templates such as {{Binary }}, {{Octal }}, {{Hexadecimal }}, etc.
Usage
[edit ]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
0x
when converting to hex, or a suffix of<sub>8</sub>
when converting to octal.
From templates
[edit ]In wikimarkup, this module may be called with a function name ntom
, e.g.:
Markup | Renders as |
---|---|
{{#invoke:BaseConvert|16to10| FF }} |
255 |
{{#invoke:BaseConvert|10to36|500}} |
DW |
{{#invoke:BaseConvert|10to16|Foo|default=0}} |
0 |
All options above are supported, excluding |base=
, |from=
and |n=
which are set by the mandatory options.
Edge cases
[edit ]Markup | Renders as |
---|---|
{{#invoke:BaseConvert|10to10|500}} |
500 |
{{#invoke:BaseConvert|10to10|FooBar}} |
FooBar |
{{#invoke:BaseConvert|10to10|FooBar|default=}} |
|
{{#invoke:BaseConvert|10to16|Foo}} |
Foo |
The above documentation is transcluded from Module:BaseConvert/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Add categories to the /doc subpage. Subpages of this module.
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Add categories to the /doc subpage. Subpages of this module.
local p = {} local digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' local function normalizeFullWidthChars(s) return mw.ustring.gsub(s, '[!-〜]', function(s) return mw.ustring.char(mw.ustring.codepoint(s, 1) - 0xFEE0) end) end local function _convert(n, base, from, precision, width, default, prefix, suffix) n = tostring(n) -- 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 -- replace any full-width Unicode characters in the string with their ASCII equivalents n = normalizeFullWidthChars(n) -- handle scientific notation with whitespace around the 'e' e.g. '5 e7' n = n:gsub('%s*[eE]%s*', 'e') 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 default or 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 local 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 (prefix or '') .. sign .. intPart .. fracPart .. (suffix or '') end function p.convert(frame) -- Allow for invocation via #invoke or directly from another module local args if frame == mw.getCurrentFrame() then args = frame.args else args = frame end local n = args.n local base = args.base local from = args.from local precision = args.precision local width = args.width local default = args.default local prefix = args.prefix local suffix = args.suffix return _convert(n, base, from, precision, width, default, prefix, suffix) end setmetatable(p, { __index = function(t, k) local from, base = k:match('^([0-9]+)to([0-9]+)$') if not from then return nil end return function(frame) local args = frame.args return _convert(mw.text.trim(args[1]), base, from, args.precision, args.width, args.default, args.prefix, args.suffix) end end }) return p